EmulateInstructionARM.cpp revision 0d91b809feae0708ec372a30d0da53959eeb062c
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdlib.h>
11
12#include "EmulateInstructionARM.h"
13#include "EmulationStateARM.h"
14#include "lldb/Core/ArchSpec.h"
15#include "lldb/Core/Address.h"
16#include "lldb/Core/ConstString.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/Stream.h"
19#include "lldb/Interpreter/OptionValueArray.h"
20#include "lldb/Interpreter/OptionValueDictionary.h"
21#include "lldb/Symbol/UnwindPlan.h"
22
23#include "Plugins/Process/Utility/ARMDefines.h"
24#include "Plugins/Process/Utility/ARMUtils.h"
25#include "Utility/ARM_DWARF_Registers.h"
26
27#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
28                                     // and countTrailingZeros function
29
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(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
177ConstString
178EmulateInstructionARM::GetPluginNameStatic ()
179{
180    static ConstString g_name("arm");
181    return g_name;
182}
183
184const char *
185EmulateInstructionARM::GetPluginDescriptionStatic ()
186{
187    return "Emulate instructions for the ARM architecture.";
188}
189
190EmulateInstruction *
191EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
192{
193    if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
194    {
195        if (arch.GetTriple().getArch() == llvm::Triple::arm)
196        {
197            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
198
199            if (emulate_insn_ap.get())
200                return emulate_insn_ap.release();
201        }
202        else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
203        {
204            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
205
206            if (emulate_insn_ap.get())
207                return emulate_insn_ap.release();
208        }
209    }
210
211    return NULL;
212}
213
214bool
215EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
216{
217    if (arch.GetTriple().getArch () == llvm::Triple::arm)
218        return true;
219    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
220        return true;
221
222    return false;
223}
224
225// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
226bool
227EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
228{
229    EmulateInstruction::Context context;
230    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
231    context.SetNoArgs ();
232
233    uint32_t random_data = rand ();
234    const uint32_t addr_byte_size = GetAddressByteSize();
235
236    if (!MemAWrite (context, address, random_data, addr_byte_size))
237        return false;
238
239    return true;
240}
241
242// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
243bool
244EmulateInstructionARM::WriteBits32Unknown (int n)
245{
246    EmulateInstruction::Context context;
247    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
248    context.SetNoArgs ();
249
250    bool success;
251    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
252
253    if (!success)
254        return false;
255
256    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
257        return false;
258
259    return true;
260}
261
262bool
263EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
264{
265    if (reg_kind == eRegisterKindGeneric)
266    {
267        switch (reg_num)
268        {
269            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
270            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
271            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
272            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
273            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
274            default: return false;
275        }
276    }
277
278    if (reg_kind == eRegisterKindDWARF)
279        return GetARMDWARFRegisterInfo(reg_num, reg_info);
280    return false;
281}
282
283uint32_t
284EmulateInstructionARM::GetFramePointerRegisterNumber () const
285{
286    if (m_opcode_mode == eModeThumb)
287    {
288        switch (m_arch.GetTriple().getOS())
289        {
290            case llvm::Triple::Darwin:
291            case llvm::Triple::MacOSX:
292            case llvm::Triple::IOS:
293                return 7;
294            default:
295                break;
296        }
297    }
298    return 11;
299}
300
301uint32_t
302EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
303{
304    if (m_opcode_mode == eModeThumb)
305    {
306        switch (m_arch.GetTriple().getOS())
307        {
308            case llvm::Triple::Darwin:
309            case llvm::Triple::MacOSX:
310            case llvm::Triple::IOS:
311                return dwarf_r7;
312            default:
313                break;
314        }
315    }
316    return dwarf_r11;
317}
318
319// Push Multiple Registers stores multiple registers to the stack, storing to
320// consecutive memory locations ending just below the address in SP, and updates
321// SP to point to the start of the stored data.
322bool
323EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
324{
325#if 0
326    // ARM pseudo code...
327    if (ConditionPassed())
328    {
329        EncodingSpecificOperations();
330        NullCheckIfThumbEE(13);
331        address = SP - 4*BitCount(registers);
332
333        for (i = 0 to 14)
334        {
335            if (registers<i> == '1')
336            {
337                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
338                    MemA[address,4] = bits(32) UNKNOWN;
339                else
340                    MemA[address,4] = R[i];
341                address = address + 4;
342            }
343        }
344
345        if (registers<15> == '1') // Only possible for encoding A1 or A2
346            MemA[address,4] = PCStoreValue();
347
348        SP = SP - 4*BitCount(registers);
349    }
350#endif
351
352    bool conditional = false;
353    bool success = false;
354    if (ConditionPassed(opcode, &conditional))
355    {
356        const uint32_t addr_byte_size = GetAddressByteSize();
357        const addr_t sp = ReadCoreReg (SP_REG, &success);
358        if (!success)
359            return false;
360        uint32_t registers = 0;
361        uint32_t Rt; // the source register
362        switch (encoding) {
363        case eEncodingT1:
364            registers = Bits32(opcode, 7, 0);
365            // The M bit represents LR.
366            if (Bit32(opcode, 8))
367                registers |= (1u << 14);
368            // if BitCount(registers) < 1 then UNPREDICTABLE;
369            if (BitCount(registers) < 1)
370                return false;
371            break;
372        case eEncodingT2:
373            // Ignore bits 15 & 13.
374            registers = Bits32(opcode, 15, 0) & ~0xa000;
375            // if BitCount(registers) < 2 then UNPREDICTABLE;
376            if (BitCount(registers) < 2)
377                return false;
378            break;
379        case eEncodingT3:
380            Rt = Bits32(opcode, 15, 12);
381            // if BadReg(t) then UNPREDICTABLE;
382            if (BadReg(Rt))
383                return false;
384            registers = (1u << Rt);
385            break;
386        case eEncodingA1:
387            registers = Bits32(opcode, 15, 0);
388            // Instead of return false, let's handle the following case as well,
389            // which amounts to pushing one reg onto the full descending stacks.
390            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
391            break;
392        case eEncodingA2:
393            Rt = Bits32(opcode, 15, 12);
394            // if t == 13 then UNPREDICTABLE;
395            if (Rt == dwarf_sp)
396                return false;
397            registers = (1u << Rt);
398            break;
399        default:
400            return false;
401        }
402        addr_t sp_offset = addr_byte_size * BitCount (registers);
403        addr_t addr = sp - sp_offset;
404        uint32_t i;
405
406        EmulateInstruction::Context context;
407        if (conditional)
408            context.type = EmulateInstruction::eContextRegisterStore;
409        else
410            context.type = EmulateInstruction::eContextPushRegisterOnStack;
411        RegisterInfo reg_info;
412        RegisterInfo sp_reg;
413        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
414        for (i=0; i<15; ++i)
415        {
416            if (BitIsSet (registers, i))
417            {
418                GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
419                context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
420                uint32_t reg_value = ReadCoreReg(i, &success);
421                if (!success)
422                    return false;
423                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
424                    return false;
425                addr += addr_byte_size;
426            }
427        }
428
429        if (BitIsSet (registers, 15))
430        {
431            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
432            context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
433            const uint32_t pc = ReadCoreReg(PC_REG, &success);
434            if (!success)
435                return false;
436            if (!MemAWrite (context, addr, pc, addr_byte_size))
437                return false;
438        }
439
440        context.type = EmulateInstruction::eContextAdjustStackPointer;
441        context.SetImmediateSigned (-sp_offset);
442
443        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
444            return false;
445    }
446    return true;
447}
448
449// Pop Multiple Registers loads multiple registers from the stack, loading from
450// consecutive memory locations staring at the address in SP, and updates
451// SP to point just above the loaded data.
452bool
453EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
454{
455#if 0
456    // ARM pseudo code...
457    if (ConditionPassed())
458    {
459        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
460        address = SP;
461        for i = 0 to 14
462            if registers<i> == '1' then
463                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
464        if registers<15> == '1' then
465            if UnalignedAllowed then
466                LoadWritePC(MemU[address,4]);
467            else
468                LoadWritePC(MemA[address,4]);
469        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
470        if registers<13> == '1' then SP = bits(32) UNKNOWN;
471    }
472#endif
473
474    bool success = false;
475
476    bool conditional = false;
477    if (ConditionPassed(opcode, &conditional))
478    {
479        const uint32_t addr_byte_size = GetAddressByteSize();
480        const addr_t sp = ReadCoreReg (SP_REG, &success);
481        if (!success)
482            return false;
483        uint32_t registers = 0;
484        uint32_t Rt; // the destination register
485        switch (encoding) {
486        case eEncodingT1:
487            registers = Bits32(opcode, 7, 0);
488            // The P bit represents PC.
489            if (Bit32(opcode, 8))
490                registers |= (1u << 15);
491            // if BitCount(registers) < 1 then UNPREDICTABLE;
492            if (BitCount(registers) < 1)
493                return false;
494            break;
495        case eEncodingT2:
496            // Ignore bit 13.
497            registers = Bits32(opcode, 15, 0) & ~0x2000;
498            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
499            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
500                return false;
501            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
502            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
503                return false;
504            break;
505        case eEncodingT3:
506            Rt = Bits32(opcode, 15, 12);
507            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
508            if (Rt == 13)
509                return false;
510            if (Rt == 15 && InITBlock() && !LastInITBlock())
511                return false;
512            registers = (1u << Rt);
513            break;
514        case eEncodingA1:
515            registers = Bits32(opcode, 15, 0);
516            // Instead of return false, let's handle the following case as well,
517            // which amounts to popping one reg from the full descending stacks.
518            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
519
520            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
521            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
522                return false;
523            break;
524        case eEncodingA2:
525            Rt = Bits32(opcode, 15, 12);
526            // if t == 13 then UNPREDICTABLE;
527            if (Rt == dwarf_sp)
528                return false;
529            registers = (1u << Rt);
530            break;
531        default:
532            return false;
533        }
534        addr_t sp_offset = addr_byte_size * BitCount (registers);
535        addr_t addr = sp;
536        uint32_t i, data;
537
538        EmulateInstruction::Context context;
539        if (conditional)
540            context.type = EmulateInstruction::eContextRegisterLoad;
541        else
542            context.type = EmulateInstruction::eContextPopRegisterOffStack;
543
544        RegisterInfo sp_reg;
545        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
546
547        for (i=0; i<15; ++i)
548        {
549            if (BitIsSet (registers, i))
550            {
551                context.SetRegisterPlusOffset (sp_reg, addr - sp);
552                data = MemARead(context, addr, 4, 0, &success);
553                if (!success)
554                    return false;
555                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
556                    return false;
557                addr += addr_byte_size;
558            }
559        }
560
561        if (BitIsSet (registers, 15))
562        {
563            context.SetRegisterPlusOffset (sp_reg, addr - sp);
564            data = MemARead(context, addr, 4, 0, &success);
565            if (!success)
566                return false;
567            // In ARMv5T and above, this is an interworking branch.
568            if (!LoadWritePC(context, data))
569                return false;
570            //addr += addr_byte_size;
571        }
572
573        context.type = EmulateInstruction::eContextAdjustStackPointer;
574        context.SetImmediateSigned (sp_offset);
575
576        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
577            return false;
578    }
579    return true;
580}
581
582// Set r7 or ip to point to saved value residing within the stack.
583// ADD (SP plus immediate)
584bool
585EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
586{
587#if 0
588    // ARM pseudo code...
589    if (ConditionPassed())
590    {
591        EncodingSpecificOperations();
592        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
593        if d == 15 then
594           ALUWritePC(result); // setflags is always FALSE here
595        else
596            R[d] = result;
597            if setflags then
598                APSR.N = result<31>;
599                APSR.Z = IsZeroBit(result);
600                APSR.C = carry;
601                APSR.V = overflow;
602    }
603#endif
604
605    bool success = false;
606
607    if (ConditionPassed(opcode))
608    {
609        const addr_t sp = ReadCoreReg (SP_REG, &success);
610        if (!success)
611            return false;
612        uint32_t Rd; // the destination register
613        uint32_t imm32;
614        switch (encoding) {
615        case eEncodingT1:
616            Rd = 7;
617            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
618            break;
619        case eEncodingA1:
620            Rd = Bits32(opcode, 15, 12);
621            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
622            break;
623        default:
624            return false;
625        }
626        addr_t sp_offset = imm32;
627        addr_t addr = sp + sp_offset; // a pointer to the stack area
628
629        EmulateInstruction::Context context;
630        context.type = eContextSetFramePointer;
631        RegisterInfo sp_reg;
632        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
633        context.SetRegisterPlusOffset (sp_reg, sp_offset);
634
635        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
636            return false;
637    }
638    return true;
639}
640
641// Set r7 or ip to the current stack pointer.
642// MOV (register)
643bool
644EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
645{
646#if 0
647    // ARM pseudo code...
648    if (ConditionPassed())
649    {
650        EncodingSpecificOperations();
651        result = R[m];
652        if d == 15 then
653            ALUWritePC(result); // setflags is always FALSE here
654        else
655            R[d] = result;
656            if setflags then
657                APSR.N = result<31>;
658                APSR.Z = IsZeroBit(result);
659                // APSR.C unchanged
660                // APSR.V unchanged
661    }
662#endif
663
664    bool success = false;
665
666    if (ConditionPassed(opcode))
667    {
668        const addr_t sp = ReadCoreReg (SP_REG, &success);
669        if (!success)
670            return false;
671        uint32_t Rd; // the destination register
672        switch (encoding) {
673        case eEncodingT1:
674            Rd = 7;
675            break;
676        case eEncodingA1:
677            Rd = 12;
678            break;
679        default:
680            return false;
681        }
682
683        EmulateInstruction::Context context;
684        if (Rd == GetFramePointerRegisterNumber())
685            context.type = EmulateInstruction::eContextSetFramePointer;
686        else
687            context.type = EmulateInstruction::eContextRegisterPlusOffset;
688        RegisterInfo sp_reg;
689        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
690        context.SetRegisterPlusOffset (sp_reg, 0);
691
692        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
693            return false;
694    }
695    return true;
696}
697
698// Move from high register (r8-r15) to low register (r0-r7).
699// MOV (register)
700bool
701EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
702{
703    return EmulateMOVRdRm (opcode, encoding);
704}
705
706// Move from register to register.
707// MOV (register)
708bool
709EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
710{
711#if 0
712    // ARM pseudo code...
713    if (ConditionPassed())
714    {
715        EncodingSpecificOperations();
716        result = R[m];
717        if d == 15 then
718            ALUWritePC(result); // setflags is always FALSE here
719        else
720            R[d] = result;
721            if setflags then
722                APSR.N = result<31>;
723                APSR.Z = IsZeroBit(result);
724                // APSR.C unchanged
725                // APSR.V unchanged
726    }
727#endif
728
729    bool success = false;
730
731    if (ConditionPassed(opcode))
732    {
733        uint32_t Rm; // the source register
734        uint32_t Rd; // the destination register
735        bool setflags;
736        switch (encoding) {
737        case eEncodingT1:
738            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
739            Rm = Bits32(opcode, 6, 3);
740            setflags = false;
741            if (Rd == 15 && InITBlock() && !LastInITBlock())
742                return false;
743            break;
744        case eEncodingT2:
745            Rd = Bits32(opcode, 2, 0);
746            Rm = Bits32(opcode, 5, 3);
747            setflags = true;
748            if (InITBlock())
749                return false;
750            break;
751        case eEncodingT3:
752            Rd = Bits32(opcode, 11, 8);
753            Rm = Bits32(opcode, 3, 0);
754            setflags = BitIsSet(opcode, 20);
755            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
756            if (setflags && (BadReg(Rd) || BadReg(Rm)))
757                return false;
758            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
759            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
760                return false;
761            break;
762        case eEncodingA1:
763            Rd = Bits32(opcode, 15, 12);
764            Rm = Bits32(opcode, 3, 0);
765            setflags = BitIsSet(opcode, 20);
766
767            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
768            if (Rd == 15 && setflags)
769                return EmulateSUBSPcLrEtc (opcode, encoding);
770            break;
771        default:
772            return false;
773        }
774        uint32_t result = ReadCoreReg(Rm, &success);
775        if (!success)
776            return false;
777
778        // The context specifies that Rm is to be moved into Rd.
779        EmulateInstruction::Context context;
780        context.type = EmulateInstruction::eContextRegisterLoad;
781        RegisterInfo dwarf_reg;
782        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
783        context.SetRegister (dwarf_reg);
784
785        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
786            return false;
787    }
788    return true;
789}
790
791// Move (immediate) writes an immediate value to the destination register.  It
792// can optionally update the condition flags based on the value.
793// MOV (immediate)
794bool
795EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
796{
797#if 0
798    // ARM pseudo code...
799    if (ConditionPassed())
800    {
801        EncodingSpecificOperations();
802        result = imm32;
803        if d == 15 then         // Can only occur for ARM encoding
804            ALUWritePC(result); // setflags is always FALSE here
805        else
806            R[d] = result;
807            if setflags then
808                APSR.N = result<31>;
809                APSR.Z = IsZeroBit(result);
810                APSR.C = carry;
811                // APSR.V unchanged
812    }
813#endif
814
815    if (ConditionPassed(opcode))
816    {
817        uint32_t Rd; // the destination register
818        uint32_t imm32; // the immediate value to be written to Rd
819        uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
820                            // for setflags == false, this value is a don't care
821                            // initialized to 0 to silence the static analyzer
822        bool setflags;
823        switch (encoding) {
824            case eEncodingT1:
825                Rd = Bits32(opcode, 10, 8);
826                setflags = !InITBlock();
827                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
828                carry = APSR_C;
829
830                break;
831
832            case eEncodingT2:
833                Rd = Bits32(opcode, 11, 8);
834                setflags = BitIsSet(opcode, 20);
835                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
836                if (BadReg(Rd))
837                  return false;
838
839                break;
840
841            case eEncodingT3:
842            {
843                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
844                Rd = Bits32 (opcode, 11, 8);
845                setflags = false;
846                uint32_t imm4 = Bits32 (opcode, 19, 16);
847                uint32_t imm3 = Bits32 (opcode, 14, 12);
848                uint32_t i = Bit32 (opcode, 26);
849                uint32_t imm8 = Bits32 (opcode, 7, 0);
850                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
851
852                // if BadReg(d) then UNPREDICTABLE;
853                if (BadReg (Rd))
854                    return false;
855            }
856                break;
857
858            case eEncodingA1:
859                // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
860                Rd = Bits32 (opcode, 15, 12);
861                setflags = BitIsSet (opcode, 20);
862                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
863
864                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
865                if ((Rd == 15) && setflags)
866                    return EmulateSUBSPcLrEtc (opcode, encoding);
867
868                break;
869
870            case eEncodingA2:
871            {
872                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
873                Rd = Bits32 (opcode, 15, 12);
874                setflags = false;
875                uint32_t imm4 = Bits32 (opcode, 19, 16);
876                uint32_t imm12 = Bits32 (opcode, 11, 0);
877                imm32 = (imm4 << 12) | imm12;
878
879                // if d == 15 then UNPREDICTABLE;
880                if (Rd == 15)
881                    return false;
882            }
883                break;
884
885            default:
886                return false;
887        }
888        uint32_t result = imm32;
889
890        // The context specifies that an immediate is to be moved into Rd.
891        EmulateInstruction::Context context;
892        context.type = EmulateInstruction::eContextImmediate;
893        context.SetNoArgs ();
894
895        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
896            return false;
897    }
898    return true;
899}
900
901// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
902// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
903// unsigned values.
904//
905// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
906// limited to only a few forms of the instruction.
907bool
908EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
909{
910#if 0
911    if ConditionPassed() then
912        EncodingSpecificOperations();
913        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
914        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
915        result = operand1 * operand2;
916        R[d] = result<31:0>;
917        if setflags then
918            APSR.N = result<31>;
919            APSR.Z = IsZeroBit(result);
920            if ArchVersion() == 4 then
921                APSR.C = bit UNKNOWN;
922            // else APSR.C unchanged
923            // APSR.V always unchanged
924#endif
925
926    if (ConditionPassed(opcode))
927    {
928        uint32_t d;
929        uint32_t n;
930        uint32_t m;
931        bool setflags;
932
933        // EncodingSpecificOperations();
934        switch (encoding)
935        {
936            case eEncodingT1:
937                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
938                d = Bits32 (opcode, 2, 0);
939                n = Bits32 (opcode, 5, 3);
940                m = Bits32 (opcode, 2, 0);
941                setflags = !InITBlock();
942
943                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
944                if ((ArchVersion() < ARMv6) && (d == n))
945                    return false;
946
947                break;
948
949            case eEncodingT2:
950                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
951                d = Bits32 (opcode, 11, 8);
952                n = Bits32 (opcode, 19, 16);
953                m = Bits32 (opcode, 3, 0);
954                setflags = false;
955
956                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
957                if (BadReg (d) || BadReg (n) || BadReg (m))
958                    return false;
959
960                break;
961
962            case eEncodingA1:
963                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
964                d = Bits32 (opcode, 19, 16);
965                n = Bits32 (opcode, 3, 0);
966                m = Bits32 (opcode, 11, 8);
967                setflags = BitIsSet (opcode, 20);
968
969                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
970                if ((d == 15) ||  (n == 15) || (m == 15))
971                    return false;
972
973                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
974                if ((ArchVersion() < ARMv6) && (d == n))
975                    return false;
976
977                break;
978
979            default:
980                return false;
981        }
982
983        bool success = false;
984
985        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
986        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
987        if (!success)
988            return false;
989
990        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
991        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
992        if (!success)
993            return false;
994
995        // result = operand1 * operand2;
996        uint64_t result = operand1 * operand2;
997
998        // R[d] = result<31:0>;
999        RegisterInfo op1_reg;
1000        RegisterInfo op2_reg;
1001        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1002        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1003
1004        EmulateInstruction::Context context;
1005        context.type = eContextArithmetic;
1006        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1007
1008        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1009            return false;
1010
1011        // if setflags then
1012        if (setflags)
1013        {
1014            // APSR.N = result<31>;
1015            // APSR.Z = IsZeroBit(result);
1016            m_new_inst_cpsr = m_opcode_cpsr;
1017            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1018            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1019            if (m_new_inst_cpsr != m_opcode_cpsr)
1020            {
1021                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1022                    return false;
1023            }
1024
1025            // if ArchVersion() == 4 then
1026                // APSR.C = bit UNKNOWN;
1027        }
1028    }
1029    return true;
1030}
1031
1032// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1033// It can optionally update the condition flags based on the value.
1034bool
1035EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1036{
1037#if 0
1038    // ARM pseudo code...
1039    if (ConditionPassed())
1040    {
1041        EncodingSpecificOperations();
1042        result = NOT(imm32);
1043        if d == 15 then         // Can only occur for ARM encoding
1044            ALUWritePC(result); // setflags is always FALSE here
1045        else
1046            R[d] = result;
1047            if setflags then
1048                APSR.N = result<31>;
1049                APSR.Z = IsZeroBit(result);
1050                APSR.C = carry;
1051                // APSR.V unchanged
1052    }
1053#endif
1054
1055    if (ConditionPassed(opcode))
1056    {
1057        uint32_t Rd; // the destination register
1058        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1059        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1060        bool setflags;
1061        switch (encoding) {
1062        case eEncodingT1:
1063            Rd = Bits32(opcode, 11, 8);
1064            setflags = BitIsSet(opcode, 20);
1065            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1066            break;
1067        case eEncodingA1:
1068            Rd = Bits32(opcode, 15, 12);
1069            setflags = BitIsSet(opcode, 20);
1070            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1071
1072            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1073            if (Rd == 15 && setflags)
1074                return EmulateSUBSPcLrEtc (opcode, encoding);
1075            break;
1076        default:
1077            return false;
1078        }
1079        uint32_t result = ~imm32;
1080
1081        // The context specifies that an immediate is to be moved into Rd.
1082        EmulateInstruction::Context context;
1083        context.type = EmulateInstruction::eContextImmediate;
1084        context.SetNoArgs ();
1085
1086        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1087            return false;
1088    }
1089    return true;
1090}
1091
1092// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1093// It can optionally update the condition flags based on the result.
1094bool
1095EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1096{
1097#if 0
1098    // ARM pseudo code...
1099    if (ConditionPassed())
1100    {
1101        EncodingSpecificOperations();
1102        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1103        result = NOT(shifted);
1104        if d == 15 then         // Can only occur for ARM encoding
1105            ALUWritePC(result); // setflags is always FALSE here
1106        else
1107            R[d] = result;
1108            if setflags then
1109                APSR.N = result<31>;
1110                APSR.Z = IsZeroBit(result);
1111                APSR.C = carry;
1112                // APSR.V unchanged
1113    }
1114#endif
1115
1116    if (ConditionPassed(opcode))
1117    {
1118        uint32_t Rm; // the source register
1119        uint32_t Rd; // the destination register
1120        ARM_ShifterType shift_t;
1121        uint32_t shift_n; // the shift applied to the value read from Rm
1122        bool setflags;
1123        uint32_t carry; // the carry bit after the shift operation
1124        switch (encoding) {
1125        case eEncodingT1:
1126            Rd = Bits32(opcode, 2, 0);
1127            Rm = Bits32(opcode, 5, 3);
1128            setflags = !InITBlock();
1129            shift_t = SRType_LSL;
1130            shift_n = 0;
1131            if (InITBlock())
1132                return false;
1133            break;
1134        case eEncodingT2:
1135            Rd = Bits32(opcode, 11, 8);
1136            Rm = Bits32(opcode, 3, 0);
1137            setflags = BitIsSet(opcode, 20);
1138            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1139            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1140            if (BadReg(Rd) || BadReg(Rm))
1141                return false;
1142            break;
1143        case eEncodingA1:
1144            Rd = Bits32(opcode, 15, 12);
1145            Rm = Bits32(opcode, 3, 0);
1146            setflags = BitIsSet(opcode, 20);
1147            shift_n = DecodeImmShiftARM(opcode, shift_t);
1148            break;
1149        default:
1150            return false;
1151        }
1152        bool success = false;
1153        uint32_t value = ReadCoreReg(Rm, &success);
1154        if (!success)
1155            return false;
1156
1157        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1158        if (!success)
1159            return false;
1160        uint32_t result = ~shifted;
1161
1162        // The context specifies that an immediate is to be moved into Rd.
1163        EmulateInstruction::Context context;
1164        context.type = EmulateInstruction::eContextImmediate;
1165        context.SetNoArgs ();
1166
1167        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1168            return false;
1169    }
1170    return true;
1171}
1172
1173// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1174// LDR (literal)
1175bool
1176EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1177{
1178#if 0
1179    // ARM pseudo code...
1180    if (ConditionPassed())
1181    {
1182        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1183        base = Align(PC,4);
1184        address = if add then (base + imm32) else (base - imm32);
1185        data = MemU[address,4];
1186        if t == 15 then
1187            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1188        elsif UnalignedSupport() || address<1:0> = '00' then
1189            R[t] = data;
1190        else // Can only apply before ARMv7
1191            if CurrentInstrSet() == InstrSet_ARM then
1192                R[t] = ROR(data, 8*UInt(address<1:0>));
1193            else
1194                R[t] = bits(32) UNKNOWN;
1195    }
1196#endif
1197
1198    if (ConditionPassed(opcode))
1199    {
1200        bool success = false;
1201        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1202        if (!success)
1203            return false;
1204
1205        // PC relative immediate load context
1206        EmulateInstruction::Context context;
1207        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1208        RegisterInfo pc_reg;
1209        GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1210        context.SetRegisterPlusOffset (pc_reg, 0);
1211
1212        uint32_t Rt;    // the destination register
1213        uint32_t imm32; // immediate offset from the PC
1214        bool add;       // +imm32 or -imm32?
1215        addr_t base;    // the base address
1216        addr_t address; // the PC relative address
1217        uint32_t data;  // the literal data value from the PC relative load
1218        switch (encoding) {
1219        case eEncodingT1:
1220            Rt = Bits32(opcode, 10, 8);
1221            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1222            add = true;
1223            break;
1224        case eEncodingT2:
1225            Rt = Bits32(opcode, 15, 12);
1226            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1227            add = BitIsSet(opcode, 23);
1228            if (Rt == 15 && InITBlock() && !LastInITBlock())
1229                return false;
1230            break;
1231        default:
1232            return false;
1233        }
1234
1235        base = Align(pc, 4);
1236        if (add)
1237            address = base + imm32;
1238        else
1239            address = base - imm32;
1240
1241        context.SetRegisterPlusOffset(pc_reg, address - base);
1242        data = MemURead(context, address, 4, 0, &success);
1243        if (!success)
1244            return false;
1245
1246        if (Rt == 15)
1247        {
1248            if (Bits32(address, 1, 0) == 0)
1249            {
1250                // In ARMv5T and above, this is an interworking branch.
1251                if (!LoadWritePC(context, data))
1252                    return false;
1253            }
1254            else
1255                return false;
1256        }
1257        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1258        {
1259            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1260                return false;
1261        }
1262        else // We don't handle ARM for now.
1263            return false;
1264
1265    }
1266    return true;
1267}
1268
1269// An add operation to adjust the SP.
1270// ADD (SP plus immediate)
1271bool
1272EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1273{
1274#if 0
1275    // ARM pseudo code...
1276    if (ConditionPassed())
1277    {
1278        EncodingSpecificOperations();
1279        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1280        if d == 15 then // Can only occur for ARM encoding
1281            ALUWritePC(result); // setflags is always FALSE here
1282        else
1283            R[d] = result;
1284            if setflags then
1285                APSR.N = result<31>;
1286                APSR.Z = IsZeroBit(result);
1287                APSR.C = carry;
1288                APSR.V = overflow;
1289    }
1290#endif
1291
1292    bool success = false;
1293
1294    if (ConditionPassed(opcode))
1295    {
1296        const addr_t sp = ReadCoreReg (SP_REG, &success);
1297        if (!success)
1298            return false;
1299        uint32_t imm32; // the immediate operand
1300        uint32_t d;
1301        //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1302        switch (encoding)
1303        {
1304            case eEncodingT1:
1305                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1306                d = Bits32 (opcode, 10, 8);
1307                imm32 = (Bits32 (opcode, 7, 0) << 2);
1308
1309                break;
1310
1311            case eEncodingT2:
1312                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1313                d = 13;
1314                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1315
1316                break;
1317
1318            default:
1319                return false;
1320        }
1321        addr_t sp_offset = imm32;
1322        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1323
1324        EmulateInstruction::Context context;
1325        context.type = EmulateInstruction::eContextAdjustStackPointer;
1326        RegisterInfo sp_reg;
1327        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1328        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1329
1330        if (d == 15)
1331        {
1332            if (!ALUWritePC (context, addr))
1333                return false;
1334        }
1335        else
1336        {
1337            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1338                return false;
1339
1340            // Add this back if/when support eEncodingT3 eEncodingA1
1341            //if (setflags)
1342            //{
1343            //    APSR.N = result<31>;
1344            //    APSR.Z = IsZeroBit(result);
1345            //    APSR.C = carry;
1346            //    APSR.V = overflow;
1347            //}
1348        }
1349    }
1350    return true;
1351}
1352
1353// An add operation to adjust the SP.
1354// ADD (SP plus register)
1355bool
1356EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1357{
1358#if 0
1359    // ARM pseudo code...
1360    if (ConditionPassed())
1361    {
1362        EncodingSpecificOperations();
1363        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1364        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1365        if d == 15 then
1366            ALUWritePC(result); // setflags is always FALSE here
1367        else
1368            R[d] = result;
1369            if setflags then
1370                APSR.N = result<31>;
1371                APSR.Z = IsZeroBit(result);
1372                APSR.C = carry;
1373                APSR.V = overflow;
1374    }
1375#endif
1376
1377    bool success = false;
1378
1379    if (ConditionPassed(opcode))
1380    {
1381        const addr_t sp = ReadCoreReg (SP_REG, &success);
1382        if (!success)
1383            return false;
1384        uint32_t Rm; // the second operand
1385        switch (encoding) {
1386        case eEncodingT2:
1387            Rm = Bits32(opcode, 6, 3);
1388            break;
1389        default:
1390            return false;
1391        }
1392        int32_t reg_value = ReadCoreReg(Rm, &success);
1393        if (!success)
1394            return false;
1395
1396        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1397
1398        EmulateInstruction::Context context;
1399        context.type = eContextArithmetic;
1400        RegisterInfo sp_reg;
1401        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1402
1403        RegisterInfo other_reg;
1404        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1405        context.SetRegisterRegisterOperands (sp_reg, other_reg);
1406
1407        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1408            return false;
1409    }
1410    return true;
1411}
1412
1413// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1414// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1415// from Thumb to ARM.
1416// BLX (immediate)
1417bool
1418EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1419{
1420#if 0
1421    // ARM pseudo code...
1422    if (ConditionPassed())
1423    {
1424        EncodingSpecificOperations();
1425        if CurrentInstrSet() == InstrSet_ARM then
1426            LR = PC - 4;
1427        else
1428            LR = PC<31:1> : '1';
1429        if targetInstrSet == InstrSet_ARM then
1430            targetAddress = Align(PC,4) + imm32;
1431        else
1432            targetAddress = PC + imm32;
1433        SelectInstrSet(targetInstrSet);
1434        BranchWritePC(targetAddress);
1435    }
1436#endif
1437
1438    bool success = true;
1439
1440    if (ConditionPassed(opcode))
1441    {
1442        EmulateInstruction::Context context;
1443        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1444        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1445        if (!success)
1446            return false;
1447        addr_t lr; // next instruction address
1448        addr_t target; // target address
1449        int32_t imm32; // PC-relative offset
1450        switch (encoding) {
1451        case eEncodingT1:
1452            {
1453            lr = pc | 1u; // return address
1454            uint32_t S = Bit32(opcode, 26);
1455            uint32_t imm10 = Bits32(opcode, 25, 16);
1456            uint32_t J1 = Bit32(opcode, 13);
1457            uint32_t J2 = Bit32(opcode, 11);
1458            uint32_t imm11 = Bits32(opcode, 10, 0);
1459            uint32_t I1 = !(J1 ^ S);
1460            uint32_t I2 = !(J2 ^ S);
1461            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1462            imm32 = llvm::SignExtend32<25>(imm25);
1463            target = pc + imm32;
1464            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1465            if (InITBlock() && !LastInITBlock())
1466                return false;
1467            break;
1468            }
1469        case eEncodingT2:
1470            {
1471            lr = pc | 1u; // return address
1472            uint32_t S = Bit32(opcode, 26);
1473            uint32_t imm10H = Bits32(opcode, 25, 16);
1474            uint32_t J1 = Bit32(opcode, 13);
1475            uint32_t J2 = Bit32(opcode, 11);
1476            uint32_t imm10L = Bits32(opcode, 10, 1);
1477            uint32_t I1 = !(J1 ^ S);
1478            uint32_t I2 = !(J2 ^ S);
1479            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1480            imm32 = llvm::SignExtend32<25>(imm25);
1481            target = Align(pc, 4) + imm32;
1482            context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1483            if (InITBlock() && !LastInITBlock())
1484                return false;
1485            break;
1486            }
1487        case eEncodingA1:
1488            lr = pc - 4; // return address
1489            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1490            target = Align(pc, 4) + imm32;
1491            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1492            break;
1493        case eEncodingA2:
1494            lr = pc - 4; // return address
1495            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1496            target = pc + imm32;
1497            context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1498            break;
1499        default:
1500            return false;
1501        }
1502        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1503            return false;
1504        if (!BranchWritePC(context, target))
1505            return false;
1506    }
1507    return true;
1508}
1509
1510// Branch with Link and Exchange (register) calls a subroutine at an address and
1511// instruction set specified by a register.
1512// BLX (register)
1513bool
1514EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1515{
1516#if 0
1517    // ARM pseudo code...
1518    if (ConditionPassed())
1519    {
1520        EncodingSpecificOperations();
1521        target = R[m];
1522        if CurrentInstrSet() == InstrSet_ARM then
1523            next_instr_addr = PC - 4;
1524            LR = next_instr_addr;
1525        else
1526            next_instr_addr = PC - 2;
1527            LR = next_instr_addr<31:1> : '1';
1528        BXWritePC(target);
1529    }
1530#endif
1531
1532    bool success = false;
1533
1534    if (ConditionPassed(opcode))
1535    {
1536        EmulateInstruction::Context context;
1537        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1538        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1539        addr_t lr; // next instruction address
1540        if (!success)
1541            return false;
1542        uint32_t Rm; // the register with the target address
1543        switch (encoding) {
1544        case eEncodingT1:
1545            lr = (pc - 2) | 1u; // return address
1546            Rm = Bits32(opcode, 6, 3);
1547            // if m == 15 then UNPREDICTABLE;
1548            if (Rm == 15)
1549                return false;
1550            if (InITBlock() && !LastInITBlock())
1551                return false;
1552            break;
1553        case eEncodingA1:
1554            lr = pc - 4; // return address
1555            Rm = Bits32(opcode, 3, 0);
1556            // if m == 15 then UNPREDICTABLE;
1557            if (Rm == 15)
1558                return false;
1559            break;
1560        default:
1561            return false;
1562        }
1563        addr_t target = ReadCoreReg (Rm, &success);
1564        if (!success)
1565            return false;
1566        RegisterInfo dwarf_reg;
1567        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1568        context.SetRegister (dwarf_reg);
1569        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1570            return false;
1571        if (!BXWritePC(context, target))
1572            return false;
1573    }
1574    return true;
1575}
1576
1577// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1578bool
1579EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1580{
1581#if 0
1582    // ARM pseudo code...
1583    if (ConditionPassed())
1584    {
1585        EncodingSpecificOperations();
1586        BXWritePC(R[m]);
1587    }
1588#endif
1589
1590    if (ConditionPassed(opcode))
1591    {
1592        EmulateInstruction::Context context;
1593        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1594        uint32_t Rm; // the register with the target address
1595        switch (encoding) {
1596        case eEncodingT1:
1597            Rm = Bits32(opcode, 6, 3);
1598            if (InITBlock() && !LastInITBlock())
1599                return false;
1600            break;
1601        case eEncodingA1:
1602            Rm = Bits32(opcode, 3, 0);
1603            break;
1604        default:
1605            return false;
1606        }
1607        bool success = false;
1608        addr_t target = ReadCoreReg (Rm, &success);
1609        if (!success)
1610            return false;
1611
1612        RegisterInfo dwarf_reg;
1613        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1614        context.SetRegister (dwarf_reg);
1615        if (!BXWritePC(context, target))
1616            return false;
1617    }
1618    return true;
1619}
1620
1621// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1622// address and instruction set specified by a register as though it were a BX instruction.
1623//
1624// TODO: Emulate Jazelle architecture?
1625//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1626bool
1627EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1628{
1629#if 0
1630    // ARM pseudo code...
1631    if (ConditionPassed())
1632    {
1633        EncodingSpecificOperations();
1634        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1635            BXWritePC(R[m]);
1636        else
1637            if JazelleAcceptsExecution() then
1638                SwitchToJazelleExecution();
1639            else
1640                SUBARCHITECTURE_DEFINED handler call;
1641    }
1642#endif
1643
1644    if (ConditionPassed(opcode))
1645    {
1646        EmulateInstruction::Context context;
1647        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1648        uint32_t Rm; // the register with the target address
1649        switch (encoding) {
1650        case eEncodingT1:
1651            Rm = Bits32(opcode, 19, 16);
1652            if (BadReg(Rm))
1653                return false;
1654            if (InITBlock() && !LastInITBlock())
1655                return false;
1656            break;
1657        case eEncodingA1:
1658            Rm = Bits32(opcode, 3, 0);
1659            if (Rm == 15)
1660                return false;
1661            break;
1662        default:
1663            return false;
1664        }
1665        bool success = false;
1666        addr_t target = ReadCoreReg (Rm, &success);
1667        if (!success)
1668            return false;
1669
1670        RegisterInfo dwarf_reg;
1671        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1672        context.SetRegister (dwarf_reg);
1673        if (!BXWritePC(context, target))
1674            return false;
1675    }
1676    return true;
1677}
1678
1679// Set r7 to point to some ip offset.
1680// SUB (immediate)
1681bool
1682EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1683{
1684#if 0
1685    // ARM pseudo code...
1686    if (ConditionPassed())
1687    {
1688        EncodingSpecificOperations();
1689        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1690        if d == 15 then // Can only occur for ARM encoding
1691           ALUWritePC(result); // setflags is always FALSE here
1692        else
1693            R[d] = result;
1694            if setflags then
1695                APSR.N = result<31>;
1696                APSR.Z = IsZeroBit(result);
1697                APSR.C = carry;
1698                APSR.V = overflow;
1699    }
1700#endif
1701
1702    if (ConditionPassed(opcode))
1703    {
1704        bool success = false;
1705        const addr_t ip = ReadCoreReg (12, &success);
1706        if (!success)
1707            return false;
1708        uint32_t imm32;
1709        switch (encoding) {
1710        case eEncodingA1:
1711            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1712            break;
1713        default:
1714            return false;
1715        }
1716        addr_t ip_offset = imm32;
1717        addr_t addr = ip - ip_offset; // the adjusted ip value
1718
1719        EmulateInstruction::Context context;
1720        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1721        RegisterInfo dwarf_reg;
1722        GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1723        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1724
1725        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1726            return false;
1727    }
1728    return true;
1729}
1730
1731// Set ip to point to some stack offset.
1732// SUB (SP minus immediate)
1733bool
1734EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1735{
1736#if 0
1737    // ARM pseudo code...
1738    if (ConditionPassed())
1739    {
1740        EncodingSpecificOperations();
1741        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1742        if d == 15 then // Can only occur for ARM encoding
1743           ALUWritePC(result); // setflags is always FALSE here
1744        else
1745            R[d] = result;
1746            if setflags then
1747                APSR.N = result<31>;
1748                APSR.Z = IsZeroBit(result);
1749                APSR.C = carry;
1750                APSR.V = overflow;
1751    }
1752#endif
1753
1754    if (ConditionPassed(opcode))
1755    {
1756        bool success = false;
1757        const addr_t sp = ReadCoreReg (SP_REG, &success);
1758        if (!success)
1759            return false;
1760        uint32_t imm32;
1761        switch (encoding) {
1762        case eEncodingA1:
1763            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1764            break;
1765        default:
1766            return false;
1767        }
1768        addr_t sp_offset = imm32;
1769        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1770
1771        EmulateInstruction::Context context;
1772        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1773        RegisterInfo dwarf_reg;
1774        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1775        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1776
1777        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1778            return false;
1779    }
1780    return true;
1781}
1782
1783// This instruction subtracts an immediate value from the SP value, and writes
1784// the result to the destination register.
1785//
1786// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1787bool
1788EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1789{
1790#if 0
1791    // ARM pseudo code...
1792    if (ConditionPassed())
1793    {
1794        EncodingSpecificOperations();
1795        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1796        if d == 15 then        // Can only occur for ARM encoding
1797           ALUWritePC(result); // setflags is always FALSE here
1798        else
1799            R[d] = result;
1800            if setflags then
1801                APSR.N = result<31>;
1802                APSR.Z = IsZeroBit(result);
1803                APSR.C = carry;
1804                APSR.V = overflow;
1805    }
1806#endif
1807
1808    bool success = false;
1809    if (ConditionPassed(opcode))
1810    {
1811        const addr_t sp = ReadCoreReg (SP_REG, &success);
1812        if (!success)
1813            return false;
1814
1815        uint32_t Rd;
1816        bool setflags;
1817        uint32_t imm32;
1818        switch (encoding) {
1819        case eEncodingT1:
1820            Rd = 13;
1821            setflags = false;
1822            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1823            break;
1824        case eEncodingT2:
1825            Rd = Bits32(opcode, 11, 8);
1826            setflags = BitIsSet(opcode, 20);
1827            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1828            if (Rd == 15 && setflags)
1829                return EmulateCMPImm(opcode, eEncodingT2);
1830            if (Rd == 15 && !setflags)
1831                return false;
1832            break;
1833        case eEncodingT3:
1834            Rd = Bits32(opcode, 11, 8);
1835            setflags = false;
1836            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1837            if (Rd == 15)
1838                return false;
1839            break;
1840        case eEncodingA1:
1841            Rd = Bits32(opcode, 15, 12);
1842            setflags = BitIsSet(opcode, 20);
1843            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1844
1845            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1846            if (Rd == 15 && setflags)
1847                return EmulateSUBSPcLrEtc (opcode, encoding);
1848            break;
1849        default:
1850            return false;
1851        }
1852        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1853
1854        EmulateInstruction::Context context;
1855        if (Rd == 13)
1856        {
1857            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1858                                     // value gets passed down to context.SetImmediateSigned.
1859            context.type = EmulateInstruction::eContextAdjustStackPointer;
1860            context.SetImmediateSigned (-imm64); // the stack pointer offset
1861        }
1862        else
1863        {
1864            context.type = EmulateInstruction::eContextImmediate;
1865            context.SetNoArgs ();
1866        }
1867
1868        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1869            return false;
1870    }
1871    return true;
1872}
1873
1874// A store operation to the stack that also updates the SP.
1875bool
1876EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1877{
1878#if 0
1879    // ARM pseudo code...
1880    if (ConditionPassed())
1881    {
1882        EncodingSpecificOperations();
1883        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1884        address = if index then offset_addr else R[n];
1885        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1886        if wback then R[n] = offset_addr;
1887    }
1888#endif
1889
1890    bool conditional = false;
1891    bool success = false;
1892    if (ConditionPassed(opcode, &conditional))
1893    {
1894        const uint32_t addr_byte_size = GetAddressByteSize();
1895        const addr_t sp = ReadCoreReg (SP_REG, &success);
1896        if (!success)
1897            return false;
1898        uint32_t Rt; // the source register
1899        uint32_t imm12;
1900        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1901
1902        bool index;
1903        bool add;
1904        bool wback;
1905        switch (encoding) {
1906        case eEncodingA1:
1907            Rt = Bits32(opcode, 15, 12);
1908            imm12 = Bits32(opcode, 11, 0);
1909            Rn = Bits32 (opcode, 19, 16);
1910
1911            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1912                return false;
1913
1914            index = BitIsSet (opcode, 24);
1915            add = BitIsSet (opcode, 23);
1916            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1917
1918            if (wback && ((Rn == 15) || (Rn == Rt)))
1919                return false;
1920            break;
1921        default:
1922            return false;
1923        }
1924        addr_t offset_addr;
1925        if (add)
1926            offset_addr = sp + imm12;
1927        else
1928            offset_addr = sp - imm12;
1929
1930        addr_t addr;
1931        if (index)
1932            addr = offset_addr;
1933        else
1934            addr = sp;
1935
1936        EmulateInstruction::Context context;
1937        if (conditional)
1938            context.type = EmulateInstruction::eContextRegisterStore;
1939        else
1940            context.type = EmulateInstruction::eContextPushRegisterOnStack;
1941        RegisterInfo sp_reg;
1942        RegisterInfo dwarf_reg;
1943
1944        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1945        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1946        context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1947        if (Rt != 15)
1948        {
1949            uint32_t reg_value = ReadCoreReg(Rt, &success);
1950            if (!success)
1951                return false;
1952            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1953                return false;
1954        }
1955        else
1956        {
1957            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1958            if (!success)
1959                return false;
1960            if (!MemUWrite (context, addr, pc, addr_byte_size))
1961                return false;
1962        }
1963
1964
1965        if (wback)
1966        {
1967            context.type = EmulateInstruction::eContextAdjustStackPointer;
1968            context.SetImmediateSigned (addr - sp);
1969            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1970                return false;
1971        }
1972    }
1973    return true;
1974}
1975
1976// Vector Push stores multiple extension registers to the stack.
1977// It also updates SP to point to the start of the stored data.
1978bool
1979EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1980{
1981#if 0
1982    // ARM pseudo code...
1983    if (ConditionPassed())
1984    {
1985        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1986        address = SP - imm32;
1987        SP = SP - imm32;
1988        if single_regs then
1989            for r = 0 to regs-1
1990                MemA[address,4] = S[d+r]; address = address+4;
1991        else
1992            for r = 0 to regs-1
1993                // Store as two word-aligned words in the correct order for current endianness.
1994                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1995                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1996                address = address+8;
1997    }
1998#endif
1999
2000    bool success = false;
2001    bool conditional = false;
2002    if (ConditionPassed(opcode, &conditional))
2003    {
2004        const uint32_t addr_byte_size = GetAddressByteSize();
2005        const addr_t sp = ReadCoreReg (SP_REG, &success);
2006        if (!success)
2007            return false;
2008        bool single_regs;
2009        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2010        uint32_t imm32; // stack offset
2011        uint32_t regs;  // number of registers
2012        switch (encoding) {
2013        case eEncodingT1:
2014        case eEncodingA1:
2015            single_regs = false;
2016            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2017            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2018            // If UInt(imm8) is odd, see "FSTMX".
2019            regs = Bits32(opcode, 7, 0) / 2;
2020            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2021            if (regs == 0 || regs > 16 || (d + regs) > 32)
2022                return false;
2023            break;
2024        case eEncodingT2:
2025        case eEncodingA2:
2026            single_regs = true;
2027            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2028            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2029            regs = Bits32(opcode, 7, 0);
2030            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2031            if (regs == 0 || regs > 16 || (d + regs) > 32)
2032                return false;
2033            break;
2034        default:
2035            return false;
2036        }
2037        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2038        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2039        addr_t sp_offset = imm32;
2040        addr_t addr = sp - sp_offset;
2041        uint32_t i;
2042
2043        EmulateInstruction::Context context;
2044        if (conditional)
2045            context.type = EmulateInstruction::eContextRegisterStore;
2046        else
2047            context.type = EmulateInstruction::eContextPushRegisterOnStack;
2048        RegisterInfo dwarf_reg;
2049        RegisterInfo sp_reg;
2050        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2051        for (i=0; i<regs; ++i)
2052        {
2053            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2054            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2055            // uint64_t to accommodate 64-bit registers.
2056            uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2057            if (!success)
2058                return false;
2059            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2060                return false;
2061            addr += reg_byte_size;
2062        }
2063
2064        context.type = EmulateInstruction::eContextAdjustStackPointer;
2065        context.SetImmediateSigned (-sp_offset);
2066
2067        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2068            return false;
2069    }
2070    return true;
2071}
2072
2073// Vector Pop loads multiple extension registers from the stack.
2074// It also updates SP to point just above the loaded data.
2075bool
2076EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2077{
2078#if 0
2079    // ARM pseudo code...
2080    if (ConditionPassed())
2081    {
2082        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2083        address = SP;
2084        SP = SP + imm32;
2085        if single_regs then
2086            for r = 0 to regs-1
2087                S[d+r] = MemA[address,4]; address = address+4;
2088        else
2089            for r = 0 to regs-1
2090                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2091                // Combine the word-aligned words in the correct order for current endianness.
2092                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2093    }
2094#endif
2095
2096    bool success = false;
2097    bool conditional = false;
2098    if (ConditionPassed(opcode, &conditional))
2099    {
2100        const uint32_t addr_byte_size = GetAddressByteSize();
2101        const addr_t sp = ReadCoreReg (SP_REG, &success);
2102        if (!success)
2103            return false;
2104        bool single_regs;
2105        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2106        uint32_t imm32; // stack offset
2107        uint32_t regs;  // number of registers
2108        switch (encoding) {
2109        case eEncodingT1:
2110        case eEncodingA1:
2111            single_regs = false;
2112            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2113            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2114            // If UInt(imm8) is odd, see "FLDMX".
2115            regs = Bits32(opcode, 7, 0) / 2;
2116            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2117            if (regs == 0 || regs > 16 || (d + regs) > 32)
2118                return false;
2119            break;
2120        case eEncodingT2:
2121        case eEncodingA2:
2122            single_regs = true;
2123            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2124            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2125            regs = Bits32(opcode, 7, 0);
2126            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2127            if (regs == 0 || regs > 16 || (d + regs) > 32)
2128                return false;
2129            break;
2130        default:
2131            return false;
2132        }
2133        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2134        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2135        addr_t sp_offset = imm32;
2136        addr_t addr = sp;
2137        uint32_t i;
2138        uint64_t data; // uint64_t to accomodate 64-bit registers.
2139
2140        EmulateInstruction::Context context;
2141        if (conditional)
2142            context.type = EmulateInstruction::eContextRegisterLoad;
2143        else
2144            context.type = EmulateInstruction::eContextPopRegisterOffStack;
2145        RegisterInfo dwarf_reg;
2146        RegisterInfo sp_reg;
2147        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2148        for (i=0; i<regs; ++i)
2149        {
2150            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2151            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2152            data = MemARead(context, addr, reg_byte_size, 0, &success);
2153            if (!success)
2154                return false;
2155            if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2156                return false;
2157            addr += reg_byte_size;
2158        }
2159
2160        context.type = EmulateInstruction::eContextAdjustStackPointer;
2161        context.SetImmediateSigned (sp_offset);
2162
2163        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2164            return false;
2165    }
2166    return true;
2167}
2168
2169// SVC (previously SWI)
2170bool
2171EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2172{
2173#if 0
2174    // ARM pseudo code...
2175    if (ConditionPassed())
2176    {
2177        EncodingSpecificOperations();
2178        CallSupervisor();
2179    }
2180#endif
2181
2182    bool success = false;
2183
2184    if (ConditionPassed(opcode))
2185    {
2186        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2187        addr_t lr; // next instruction address
2188        if (!success)
2189            return false;
2190        uint32_t imm32; // the immediate constant
2191        uint32_t mode;  // ARM or Thumb mode
2192        switch (encoding) {
2193        case eEncodingT1:
2194            lr = (pc + 2) | 1u; // return address
2195            imm32 = Bits32(opcode, 7, 0);
2196            mode = eModeThumb;
2197            break;
2198        case eEncodingA1:
2199            lr = pc + 4; // return address
2200            imm32 = Bits32(opcode, 23, 0);
2201            mode = eModeARM;
2202            break;
2203        default:
2204            return false;
2205        }
2206
2207        EmulateInstruction::Context context;
2208        context.type = EmulateInstruction::eContextSupervisorCall;
2209        context.SetISAAndImmediate (mode, imm32);
2210        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2211            return false;
2212    }
2213    return true;
2214}
2215
2216// If Then makes up to four following instructions (the IT block) conditional.
2217bool
2218EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2219{
2220#if 0
2221    // ARM pseudo code...
2222    EncodingSpecificOperations();
2223    ITSTATE.IT<7:0> = firstcond:mask;
2224#endif
2225
2226    m_it_session.InitIT(Bits32(opcode, 7, 0));
2227    return true;
2228}
2229
2230bool
2231EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2232{
2233    // NOP, nothing to do...
2234    return true;
2235}
2236
2237// Branch causes a branch to a target address.
2238bool
2239EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2240{
2241#if 0
2242    // ARM pseudo code...
2243    if (ConditionPassed())
2244    {
2245        EncodingSpecificOperations();
2246        BranchWritePC(PC + imm32);
2247    }
2248#endif
2249
2250    bool success = false;
2251
2252    if (ConditionPassed(opcode))
2253    {
2254        EmulateInstruction::Context context;
2255        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2256        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2257        if (!success)
2258            return false;
2259        addr_t target; // target address
2260        int32_t imm32; // PC-relative offset
2261        switch (encoding) {
2262        case eEncodingT1:
2263            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2264            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2265            target = pc + imm32;
2266            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2267            break;
2268        case eEncodingT2:
2269            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2270            target = pc + imm32;
2271            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2272            break;
2273        case eEncodingT3:
2274            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2275            {
2276            uint32_t S = Bit32(opcode, 26);
2277            uint32_t imm6 = Bits32(opcode, 21, 16);
2278            uint32_t J1 = Bit32(opcode, 13);
2279            uint32_t J2 = Bit32(opcode, 11);
2280            uint32_t imm11 = Bits32(opcode, 10, 0);
2281            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2282            imm32 = llvm::SignExtend32<21>(imm21);
2283            target = pc + imm32;
2284            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2285            break;
2286            }
2287        case eEncodingT4:
2288            {
2289            uint32_t S = Bit32(opcode, 26);
2290            uint32_t imm10 = Bits32(opcode, 25, 16);
2291            uint32_t J1 = Bit32(opcode, 13);
2292            uint32_t J2 = Bit32(opcode, 11);
2293            uint32_t imm11 = Bits32(opcode, 10, 0);
2294            uint32_t I1 = !(J1 ^ S);
2295            uint32_t I2 = !(J2 ^ S);
2296            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2297            imm32 = llvm::SignExtend32<25>(imm25);
2298            target = pc + imm32;
2299            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2300            break;
2301            }
2302        case eEncodingA1:
2303            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2304            target = pc + imm32;
2305            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2306            break;
2307        default:
2308            return false;
2309        }
2310        if (!BranchWritePC(context, target))
2311            return false;
2312    }
2313    return true;
2314}
2315
2316// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2317// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2318// CBNZ, CBZ
2319bool
2320EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2321{
2322#if 0
2323    // ARM pseudo code...
2324    EncodingSpecificOperations();
2325    if nonzero ^ IsZero(R[n]) then
2326        BranchWritePC(PC + imm32);
2327#endif
2328
2329    bool success = false;
2330
2331    // Read the register value from the operand register Rn.
2332    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2333    if (!success)
2334        return false;
2335
2336    EmulateInstruction::Context context;
2337    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2338    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2339    if (!success)
2340        return false;
2341
2342    addr_t target;  // target address
2343    uint32_t imm32; // PC-relative offset to branch forward
2344    bool nonzero;
2345    switch (encoding) {
2346    case eEncodingT1:
2347        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2348        nonzero = BitIsSet(opcode, 11);
2349        target = pc + imm32;
2350        context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2351        break;
2352    default:
2353        return false;
2354    }
2355    if (nonzero ^ (reg_val == 0))
2356        if (!BranchWritePC(context, target))
2357            return false;
2358
2359    return true;
2360}
2361
2362// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2363// A base register provides a pointer to the table, and a second register supplies an index into the table.
2364// The branch length is twice the value of the byte returned from the table.
2365//
2366// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2367// A base register provides a pointer to the table, and a second register supplies an index into the table.
2368// The branch length is twice the value of the halfword returned from the table.
2369// TBB, TBH
2370bool
2371EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2372{
2373#if 0
2374    // ARM pseudo code...
2375    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2376    if is_tbh then
2377        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2378    else
2379        halfwords = UInt(MemU[R[n]+R[m], 1]);
2380    BranchWritePC(PC + 2*halfwords);
2381#endif
2382
2383    bool success = false;
2384
2385    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2386    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2387    bool is_tbh;     // true if table branch halfword
2388    switch (encoding) {
2389    case eEncodingT1:
2390        Rn = Bits32(opcode, 19, 16);
2391        Rm = Bits32(opcode, 3, 0);
2392        is_tbh = BitIsSet(opcode, 4);
2393        if (Rn == 13 || BadReg(Rm))
2394            return false;
2395        if (InITBlock() && !LastInITBlock())
2396            return false;
2397        break;
2398    default:
2399        return false;
2400    }
2401
2402    // Read the address of the table from the operand register Rn.
2403    // The PC can be used, in which case the table immediately follows this instruction.
2404    uint32_t base = ReadCoreReg(Rm, &success);
2405    if (!success)
2406        return false;
2407
2408    // the table index
2409    uint32_t index = ReadCoreReg(Rm, &success);
2410    if (!success)
2411        return false;
2412
2413    // the offsetted table address
2414    addr_t addr = base + (is_tbh ? index*2 : index);
2415
2416    // PC-relative offset to branch forward
2417    EmulateInstruction::Context context;
2418    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2419    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2420    if (!success)
2421        return false;
2422
2423    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2424    if (!success)
2425        return false;
2426
2427    // target address
2428    addr_t target = pc + offset;
2429    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2430    context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2431
2432    if (!BranchWritePC(context, target))
2433        return false;
2434
2435    return true;
2436}
2437
2438// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2439// It can optionally update the condition flags based on the result.
2440bool
2441EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2442{
2443#if 0
2444    if ConditionPassed() then
2445        EncodingSpecificOperations();
2446        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2447        R[d] = result;
2448        if setflags then
2449            APSR.N = result<31>;
2450            APSR.Z = IsZeroBit(result);
2451            APSR.C = carry;
2452            APSR.V = overflow;
2453#endif
2454
2455    bool success = false;
2456
2457    if (ConditionPassed(opcode))
2458    {
2459        uint32_t d;
2460        uint32_t n;
2461        bool setflags;
2462        uint32_t imm32;
2463        uint32_t carry_out;
2464
2465        //EncodingSpecificOperations();
2466        switch (encoding)
2467        {
2468            case eEncodingT1:
2469                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2470                d = Bits32 (opcode, 2, 0);
2471                n = Bits32 (opcode, 5, 3);
2472                setflags = !InITBlock();
2473                imm32 = Bits32 (opcode, 8,6);
2474
2475                break;
2476
2477            case eEncodingT2:
2478                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2479                d = Bits32 (opcode, 10, 8);
2480                n = Bits32 (opcode, 10, 8);
2481                setflags = !InITBlock();
2482                imm32 = Bits32 (opcode, 7, 0);
2483
2484                break;
2485
2486            case eEncodingT3:
2487                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2488                // if Rn == '1101' then SEE ADD (SP plus immediate);
2489                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2490                d = Bits32 (opcode, 11, 8);
2491                n = Bits32 (opcode, 19, 16);
2492                setflags = BitIsSet (opcode, 20);
2493                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2494
2495                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2496                if (BadReg (d) || (n == 15))
2497                    return false;
2498
2499                break;
2500
2501            case eEncodingT4:
2502            {
2503                // if Rn == '1111' then SEE ADR;
2504                // if Rn == '1101' then SEE ADD (SP plus immediate);
2505                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2506                d = Bits32 (opcode, 11, 8);
2507                n = Bits32 (opcode, 19, 16);
2508                setflags = false;
2509                uint32_t i = Bit32 (opcode, 26);
2510                uint32_t imm3 = Bits32 (opcode, 14, 12);
2511                uint32_t imm8 = Bits32 (opcode, 7, 0);
2512                imm32 = (i << 11) | (imm3 << 8) | imm8;
2513
2514                // if BadReg(d) then UNPREDICTABLE;
2515                if (BadReg (d))
2516                    return false;
2517
2518                break;
2519            }
2520            default:
2521                return false;
2522        }
2523
2524        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2525        if (!success)
2526            return false;
2527
2528        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2529        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2530
2531        RegisterInfo reg_n;
2532        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2533
2534        EmulateInstruction::Context context;
2535        context.type = eContextArithmetic;
2536        context.SetRegisterPlusOffset (reg_n, imm32);
2537
2538        //R[d] = result;
2539        //if setflags then
2540            //APSR.N = result<31>;
2541            //APSR.Z = IsZeroBit(result);
2542            //APSR.C = carry;
2543            //APSR.V = overflow;
2544        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2545            return false;
2546
2547    }
2548    return true;
2549}
2550
2551// This instruction adds an immediate value to a register value, and writes the result to the destination
2552// register.  It can optionally update the condition flags based on the result.
2553bool
2554EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2555{
2556#if 0
2557    // ARM pseudo code...
2558    if ConditionPassed() then
2559        EncodingSpecificOperations();
2560        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2561        if d == 15 then
2562            ALUWritePC(result); // setflags is always FALSE here
2563        else
2564            R[d] = result;
2565            if setflags then
2566                APSR.N = result<31>;
2567                APSR.Z = IsZeroBit(result);
2568                APSR.C = carry;
2569                APSR.V = overflow;
2570#endif
2571
2572    bool success = false;
2573
2574    if (ConditionPassed(opcode))
2575    {
2576        uint32_t Rd, Rn;
2577        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2578        bool setflags;
2579        switch (encoding)
2580        {
2581        case eEncodingA1:
2582            Rd = Bits32(opcode, 15, 12);
2583            Rn = Bits32(opcode, 19, 16);
2584            setflags = BitIsSet(opcode, 20);
2585            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2586            break;
2587        default:
2588            return false;
2589        }
2590
2591        // Read the first operand.
2592        uint32_t val1 = ReadCoreReg(Rn, &success);
2593        if (!success)
2594            return false;
2595
2596        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2597
2598        EmulateInstruction::Context context;
2599        context.type = eContextArithmetic;
2600        RegisterInfo dwarf_reg;
2601        GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2602        context.SetRegisterPlusOffset (dwarf_reg, imm32);
2603
2604        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2605            return false;
2606    }
2607    return true;
2608}
2609
2610// This instruction adds a register value and an optionally-shifted register value, and writes the result
2611// to the destination register. It can optionally update the condition flags based on the result.
2612bool
2613EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2614{
2615#if 0
2616    // ARM pseudo code...
2617    if ConditionPassed() then
2618        EncodingSpecificOperations();
2619        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2620        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2621        if d == 15 then
2622            ALUWritePC(result); // setflags is always FALSE here
2623        else
2624            R[d] = result;
2625            if setflags then
2626                APSR.N = result<31>;
2627                APSR.Z = IsZeroBit(result);
2628                APSR.C = carry;
2629                APSR.V = overflow;
2630#endif
2631
2632    bool success = false;
2633
2634    if (ConditionPassed(opcode))
2635    {
2636        uint32_t Rd, Rn, Rm;
2637        ARM_ShifterType shift_t;
2638        uint32_t shift_n; // the shift applied to the value read from Rm
2639        bool setflags;
2640        switch (encoding)
2641        {
2642        case eEncodingT1:
2643            Rd = Bits32(opcode, 2, 0);
2644            Rn = Bits32(opcode, 5, 3);
2645            Rm = Bits32(opcode, 8, 6);
2646            setflags = !InITBlock();
2647            shift_t = SRType_LSL;
2648            shift_n = 0;
2649            break;
2650        case eEncodingT2:
2651            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2652            Rm = Bits32(opcode, 6, 3);
2653            setflags = false;
2654            shift_t = SRType_LSL;
2655            shift_n = 0;
2656            if (Rn == 15 && Rm == 15)
2657                return false;
2658            if (Rd == 15 && InITBlock() && !LastInITBlock())
2659                return false;
2660            break;
2661        case eEncodingA1:
2662            Rd = Bits32(opcode, 15, 12);
2663            Rn = Bits32(opcode, 19, 16);
2664            Rm = Bits32(opcode, 3, 0);
2665            setflags = BitIsSet(opcode, 20);
2666            shift_n = DecodeImmShiftARM(opcode, shift_t);
2667            break;
2668        default:
2669            return false;
2670        }
2671
2672        // Read the first operand.
2673        uint32_t val1 = ReadCoreReg(Rn, &success);
2674        if (!success)
2675            return false;
2676
2677        // Read the second operand.
2678        uint32_t val2 = ReadCoreReg(Rm, &success);
2679        if (!success)
2680            return false;
2681
2682        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2683        if (!success)
2684            return false;
2685        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2686
2687        EmulateInstruction::Context context;
2688        context.type = eContextArithmetic;
2689        RegisterInfo op1_reg;
2690        RegisterInfo op2_reg;
2691        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2692        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2693        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2694
2695        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2696            return false;
2697    }
2698    return true;
2699}
2700
2701// Compare Negative (immediate) adds a register value and an immediate value.
2702// It updates the condition flags based on the result, and discards the result.
2703bool
2704EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2705{
2706#if 0
2707    // ARM pseudo code...
2708    if ConditionPassed() then
2709        EncodingSpecificOperations();
2710        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2711        APSR.N = result<31>;
2712        APSR.Z = IsZeroBit(result);
2713        APSR.C = carry;
2714        APSR.V = overflow;
2715#endif
2716
2717    bool success = false;
2718
2719    uint32_t Rn; // the first operand
2720    uint32_t imm32; // the immediate value to be compared with
2721    switch (encoding) {
2722    case eEncodingT1:
2723        Rn = Bits32(opcode, 19, 16);
2724        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2725        if (Rn == 15)
2726            return false;
2727        break;
2728    case eEncodingA1:
2729        Rn = Bits32(opcode, 19, 16);
2730        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2731        break;
2732    default:
2733        return false;
2734    }
2735    // Read the register value from the operand register Rn.
2736    uint32_t reg_val = ReadCoreReg(Rn, &success);
2737    if (!success)
2738        return false;
2739
2740    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2741
2742    EmulateInstruction::Context context;
2743    context.type = EmulateInstruction::eContextImmediate;
2744    context.SetNoArgs ();
2745    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2746        return false;
2747
2748    return true;
2749}
2750
2751// Compare Negative (register) adds a register value and an optionally-shifted register value.
2752// It updates the condition flags based on the result, and discards the result.
2753bool
2754EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2755{
2756#if 0
2757    // ARM pseudo code...
2758    if ConditionPassed() then
2759        EncodingSpecificOperations();
2760        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2761        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2762        APSR.N = result<31>;
2763        APSR.Z = IsZeroBit(result);
2764        APSR.C = carry;
2765        APSR.V = overflow;
2766#endif
2767
2768    bool success = false;
2769
2770    uint32_t Rn; // the first operand
2771    uint32_t Rm; // the second operand
2772    ARM_ShifterType shift_t;
2773    uint32_t shift_n; // the shift applied to the value read from Rm
2774    switch (encoding) {
2775    case eEncodingT1:
2776        Rn = Bits32(opcode, 2, 0);
2777        Rm = Bits32(opcode, 5, 3);
2778        shift_t = SRType_LSL;
2779        shift_n = 0;
2780        break;
2781    case eEncodingT2:
2782        Rn = Bits32(opcode, 19, 16);
2783        Rm = Bits32(opcode, 3, 0);
2784        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2785        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2786        if (Rn == 15 || BadReg(Rm))
2787            return false;
2788        break;
2789    case eEncodingA1:
2790        Rn = Bits32(opcode, 19, 16);
2791        Rm = Bits32(opcode, 3, 0);
2792        shift_n = DecodeImmShiftARM(opcode, shift_t);
2793        break;
2794    default:
2795        return false;
2796    }
2797    // Read the register value from register Rn.
2798    uint32_t val1 = ReadCoreReg(Rn, &success);
2799    if (!success)
2800        return false;
2801
2802    // Read the register value from register Rm.
2803    uint32_t val2 = ReadCoreReg(Rm, &success);
2804    if (!success)
2805        return false;
2806
2807    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2808    if (!success)
2809        return false;
2810    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2811
2812    EmulateInstruction::Context context;
2813    context.type = EmulateInstruction::eContextImmediate;
2814    context.SetNoArgs();
2815    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2816        return false;
2817
2818    return true;
2819}
2820
2821// Compare (immediate) subtracts an immediate value from a register value.
2822// It updates the condition flags based on the result, and discards the result.
2823bool
2824EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2825{
2826#if 0
2827    // ARM pseudo code...
2828    if ConditionPassed() then
2829        EncodingSpecificOperations();
2830        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2831        APSR.N = result<31>;
2832        APSR.Z = IsZeroBit(result);
2833        APSR.C = carry;
2834        APSR.V = overflow;
2835#endif
2836
2837    bool success = false;
2838
2839    uint32_t Rn; // the first operand
2840    uint32_t imm32; // the immediate value to be compared with
2841    switch (encoding) {
2842    case eEncodingT1:
2843        Rn = Bits32(opcode, 10, 8);
2844        imm32 = Bits32(opcode, 7, 0);
2845        break;
2846    case eEncodingT2:
2847        Rn = Bits32(opcode, 19, 16);
2848        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2849        if (Rn == 15)
2850            return false;
2851        break;
2852    case eEncodingA1:
2853        Rn = Bits32(opcode, 19, 16);
2854        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2855        break;
2856    default:
2857        return false;
2858    }
2859    // Read the register value from the operand register Rn.
2860    uint32_t reg_val = ReadCoreReg(Rn, &success);
2861    if (!success)
2862        return false;
2863
2864    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2865
2866    EmulateInstruction::Context context;
2867    context.type = EmulateInstruction::eContextImmediate;
2868    context.SetNoArgs ();
2869    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2870        return false;
2871
2872    return true;
2873}
2874
2875// Compare (register) subtracts an optionally-shifted register value from a register value.
2876// It updates the condition flags based on the result, and discards the result.
2877bool
2878EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2879{
2880#if 0
2881    // ARM pseudo code...
2882    if ConditionPassed() then
2883        EncodingSpecificOperations();
2884        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2885        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2886        APSR.N = result<31>;
2887        APSR.Z = IsZeroBit(result);
2888        APSR.C = carry;
2889        APSR.V = overflow;
2890#endif
2891
2892    bool success = false;
2893
2894    uint32_t Rn; // the first operand
2895    uint32_t Rm; // the second operand
2896    ARM_ShifterType shift_t;
2897    uint32_t shift_n; // the shift applied to the value read from Rm
2898    switch (encoding) {
2899    case eEncodingT1:
2900        Rn = Bits32(opcode, 2, 0);
2901        Rm = Bits32(opcode, 5, 3);
2902        shift_t = SRType_LSL;
2903        shift_n = 0;
2904        break;
2905    case eEncodingT2:
2906        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2907        Rm = Bits32(opcode, 6, 3);
2908        shift_t = SRType_LSL;
2909        shift_n = 0;
2910        if (Rn < 8 && Rm < 8)
2911            return false;
2912        if (Rn == 15 || Rm == 15)
2913            return false;
2914        break;
2915    case eEncodingA1:
2916        Rn = Bits32(opcode, 19, 16);
2917        Rm = Bits32(opcode, 3, 0);
2918        shift_n = DecodeImmShiftARM(opcode, shift_t);
2919        break;
2920    default:
2921        return false;
2922    }
2923    // Read the register value from register Rn.
2924    uint32_t val1 = ReadCoreReg(Rn, &success);
2925    if (!success)
2926        return false;
2927
2928    // Read the register value from register Rm.
2929    uint32_t val2 = ReadCoreReg(Rm, &success);
2930    if (!success)
2931        return false;
2932
2933    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2934    if (!success)
2935        return false;
2936    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2937
2938    EmulateInstruction::Context context;
2939    context.type = EmulateInstruction::eContextImmediate;
2940    context.SetNoArgs();
2941    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2942        return false;
2943
2944    return true;
2945}
2946
2947// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2948// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2949// optionally update the condition flags based on the result.
2950bool
2951EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2952{
2953#if 0
2954    // ARM pseudo code...
2955    if ConditionPassed() then
2956        EncodingSpecificOperations();
2957        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2958        if d == 15 then         // Can only occur for ARM encoding
2959            ALUWritePC(result); // setflags is always FALSE here
2960        else
2961            R[d] = result;
2962            if setflags then
2963                APSR.N = result<31>;
2964                APSR.Z = IsZeroBit(result);
2965                APSR.C = carry;
2966                // APSR.V unchanged
2967#endif
2968
2969    return EmulateShiftImm (opcode, encoding, SRType_ASR);
2970}
2971
2972// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2973// shifting in copies of its sign bit, and writes the result to the destination register.
2974// The variable number of bits is read from the bottom byte of a register. It can optionally update
2975// the condition flags based on the result.
2976bool
2977EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2978{
2979#if 0
2980    // ARM pseudo code...
2981    if ConditionPassed() then
2982        EncodingSpecificOperations();
2983        shift_n = UInt(R[m]<7:0>);
2984        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2985        R[d] = result;
2986        if setflags then
2987            APSR.N = result<31>;
2988            APSR.Z = IsZeroBit(result);
2989            APSR.C = carry;
2990            // APSR.V unchanged
2991#endif
2992
2993    return EmulateShiftReg (opcode, encoding, SRType_ASR);
2994}
2995
2996// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2997// shifting in zeros, and writes the result to the destination register.  It can optionally
2998// update the condition flags based on the result.
2999bool
3000EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3001{
3002#if 0
3003    // ARM pseudo code...
3004    if ConditionPassed() then
3005        EncodingSpecificOperations();
3006        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3007        if d == 15 then         // Can only occur for ARM encoding
3008            ALUWritePC(result); // setflags is always FALSE here
3009        else
3010            R[d] = result;
3011            if setflags then
3012                APSR.N = result<31>;
3013                APSR.Z = IsZeroBit(result);
3014                APSR.C = carry;
3015                // APSR.V unchanged
3016#endif
3017
3018    return EmulateShiftImm (opcode, encoding, SRType_LSL);
3019}
3020
3021// Logical Shift Left (register) shifts a register value left by a variable number of bits,
3022// shifting in zeros, and writes the result to the destination register.  The variable number
3023// of bits is read from the bottom byte of a register. It can optionally update the condition
3024// flags based on the result.
3025bool
3026EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3027{
3028#if 0
3029    // ARM pseudo code...
3030    if ConditionPassed() then
3031        EncodingSpecificOperations();
3032        shift_n = UInt(R[m]<7:0>);
3033        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3034        R[d] = result;
3035        if setflags then
3036            APSR.N = result<31>;
3037            APSR.Z = IsZeroBit(result);
3038            APSR.C = carry;
3039            // APSR.V unchanged
3040#endif
3041
3042    return EmulateShiftReg (opcode, encoding, SRType_LSL);
3043}
3044
3045// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3046// shifting in zeros, and writes the result to the destination register.  It can optionally
3047// update the condition flags based on the result.
3048bool
3049EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3050{
3051#if 0
3052    // ARM pseudo code...
3053    if ConditionPassed() then
3054        EncodingSpecificOperations();
3055        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3056        if d == 15 then         // Can only occur for ARM encoding
3057            ALUWritePC(result); // setflags is always FALSE here
3058        else
3059            R[d] = result;
3060            if setflags then
3061                APSR.N = result<31>;
3062                APSR.Z = IsZeroBit(result);
3063                APSR.C = carry;
3064                // APSR.V unchanged
3065#endif
3066
3067    return EmulateShiftImm (opcode, encoding, SRType_LSR);
3068}
3069
3070// Logical Shift Right (register) shifts a register value right by a variable number of bits,
3071// shifting in zeros, and writes the result to the destination register.  The variable number
3072// of bits is read from the bottom byte of a register. It can optionally update the condition
3073// flags based on the result.
3074bool
3075EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3076{
3077#if 0
3078    // ARM pseudo code...
3079    if ConditionPassed() then
3080        EncodingSpecificOperations();
3081        shift_n = UInt(R[m]<7:0>);
3082        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3083        R[d] = result;
3084        if setflags then
3085            APSR.N = result<31>;
3086            APSR.Z = IsZeroBit(result);
3087            APSR.C = carry;
3088            // APSR.V unchanged
3089#endif
3090
3091    return EmulateShiftReg (opcode, encoding, SRType_LSR);
3092}
3093
3094// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3095// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3096// It can optionally update the condition flags based on the result.
3097bool
3098EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3099{
3100#if 0
3101    // ARM pseudo code...
3102    if ConditionPassed() then
3103        EncodingSpecificOperations();
3104        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3105        if d == 15 then         // Can only occur for ARM encoding
3106            ALUWritePC(result); // setflags is always FALSE here
3107        else
3108            R[d] = result;
3109            if setflags then
3110                APSR.N = result<31>;
3111                APSR.Z = IsZeroBit(result);
3112                APSR.C = carry;
3113                // APSR.V unchanged
3114#endif
3115
3116    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3117}
3118
3119// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3120// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3121// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3122// flags based on the result.
3123bool
3124EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3125{
3126#if 0
3127    // ARM pseudo code...
3128    if ConditionPassed() then
3129        EncodingSpecificOperations();
3130        shift_n = UInt(R[m]<7:0>);
3131        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3132        R[d] = result;
3133        if setflags then
3134            APSR.N = result<31>;
3135            APSR.Z = IsZeroBit(result);
3136            APSR.C = carry;
3137            // APSR.V unchanged
3138#endif
3139
3140    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3141}
3142
3143// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3144// with the carry flag shifted into bit [31].
3145//
3146// RRX can optionally update the condition flags based on the result.
3147// In that case, bit [0] is shifted into the carry flag.
3148bool
3149EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3150{
3151#if 0
3152    // ARM pseudo code...
3153    if ConditionPassed() then
3154        EncodingSpecificOperations();
3155        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3156        if d == 15 then         // Can only occur for ARM encoding
3157            ALUWritePC(result); // setflags is always FALSE here
3158        else
3159            R[d] = result;
3160            if setflags then
3161                APSR.N = result<31>;
3162                APSR.Z = IsZeroBit(result);
3163                APSR.C = carry;
3164                // APSR.V unchanged
3165#endif
3166
3167    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3168}
3169
3170bool
3171EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3172{
3173//    assert(shift_type == SRType_ASR
3174//           || shift_type == SRType_LSL
3175//           || shift_type == SRType_LSR
3176//           || shift_type == SRType_ROR
3177//           || shift_type == SRType_RRX);
3178
3179    bool success = false;
3180
3181    if (ConditionPassed(opcode))
3182    {
3183        uint32_t Rd;    // the destination register
3184        uint32_t Rm;    // the first operand register
3185        uint32_t imm5;  // encoding for the shift amount
3186        uint32_t carry; // the carry bit after the shift operation
3187        bool setflags;
3188
3189        // Special case handling!
3190        // A8.6.139 ROR (immediate) -- Encoding T1
3191        ARMEncoding use_encoding = encoding;
3192        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3193        {
3194            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3195            // have the same decoding of bit fields as the other Thumb2 shift operations.
3196            use_encoding = eEncodingT2;
3197        }
3198
3199        switch (use_encoding) {
3200        case eEncodingT1:
3201            // Due to the above special case handling!
3202            if (shift_type == SRType_ROR)
3203                return false;
3204
3205            Rd = Bits32(opcode, 2, 0);
3206            Rm = Bits32(opcode, 5, 3);
3207            setflags = !InITBlock();
3208            imm5 = Bits32(opcode, 10, 6);
3209            break;
3210        case eEncodingT2:
3211            // A8.6.141 RRX
3212            // There's no imm form of RRX instructions.
3213            if (shift_type == SRType_RRX)
3214                return false;
3215
3216            Rd = Bits32(opcode, 11, 8);
3217            Rm = Bits32(opcode, 3, 0);
3218            setflags = BitIsSet(opcode, 20);
3219            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3220            if (BadReg(Rd) || BadReg(Rm))
3221                return false;
3222            break;
3223        case eEncodingA1:
3224            Rd = Bits32(opcode, 15, 12);
3225            Rm = Bits32(opcode, 3, 0);
3226            setflags = BitIsSet(opcode, 20);
3227            imm5 = Bits32(opcode, 11, 7);
3228            break;
3229        default:
3230            return false;
3231        }
3232
3233        // A8.6.139 ROR (immediate)
3234        if (shift_type == SRType_ROR && imm5 == 0)
3235            shift_type = SRType_RRX;
3236
3237        // Get the first operand.
3238        uint32_t value = ReadCoreReg (Rm, &success);
3239        if (!success)
3240            return false;
3241
3242        // Decode the shift amount if not RRX.
3243        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3244
3245        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3246        if (!success)
3247            return false;
3248
3249        // The context specifies that an immediate is to be moved into Rd.
3250        EmulateInstruction::Context context;
3251        context.type = EmulateInstruction::eContextImmediate;
3252        context.SetNoArgs ();
3253
3254        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3255            return false;
3256    }
3257    return true;
3258}
3259
3260bool
3261EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3262{
3263    // assert(shift_type == SRType_ASR
3264    //        || shift_type == SRType_LSL
3265    //        || shift_type == SRType_LSR
3266    //        || shift_type == SRType_ROR);
3267
3268    bool success = false;
3269
3270    if (ConditionPassed(opcode))
3271    {
3272        uint32_t Rd;    // the destination register
3273        uint32_t Rn;    // the first operand register
3274        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3275        uint32_t carry; // the carry bit after the shift operation
3276        bool setflags;
3277        switch (encoding) {
3278        case eEncodingT1:
3279            Rd = Bits32(opcode, 2, 0);
3280            Rn = Rd;
3281            Rm = Bits32(opcode, 5, 3);
3282            setflags = !InITBlock();
3283            break;
3284        case eEncodingT2:
3285            Rd = Bits32(opcode, 11, 8);
3286            Rn = Bits32(opcode, 19, 16);
3287            Rm = Bits32(opcode, 3, 0);
3288            setflags = BitIsSet(opcode, 20);
3289            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3290                return false;
3291            break;
3292        case eEncodingA1:
3293            Rd = Bits32(opcode, 15, 12);
3294            Rn = Bits32(opcode, 3, 0);
3295            Rm = Bits32(opcode, 11, 8);
3296            setflags = BitIsSet(opcode, 20);
3297            if (Rd == 15 || Rn == 15 || Rm == 15)
3298                return false;
3299            break;
3300        default:
3301            return false;
3302        }
3303
3304        // Get the first operand.
3305        uint32_t value = ReadCoreReg (Rn, &success);
3306        if (!success)
3307            return false;
3308        // Get the Rm register content.
3309        uint32_t val = ReadCoreReg (Rm, &success);
3310        if (!success)
3311            return false;
3312
3313        // Get the shift amount.
3314        uint32_t amt = Bits32(val, 7, 0);
3315
3316        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3317        if (!success)
3318            return false;
3319
3320        // The context specifies that an immediate is to be moved into Rd.
3321        EmulateInstruction::Context context;
3322        context.type = EmulateInstruction::eContextImmediate;
3323        context.SetNoArgs ();
3324
3325        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3326            return false;
3327    }
3328    return true;
3329}
3330
3331// LDM loads multiple registers from consecutive memory locations, using an
3332// address from a base register.  Optionally the address just above the highest of those locations
3333// can be written back to the base register.
3334bool
3335EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3336{
3337#if 0
3338    // ARM pseudo code...
3339    if ConditionPassed()
3340        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3341        address = R[n];
3342
3343        for i = 0 to 14
3344            if registers<i> == '1' then
3345                R[i] = MemA[address, 4]; address = address + 4;
3346        if registers<15> == '1' then
3347            LoadWritePC (MemA[address, 4]);
3348
3349        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3350        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3351
3352#endif
3353
3354    bool success = false;
3355    bool conditional = false;
3356    if (ConditionPassed(opcode, &conditional))
3357    {
3358        uint32_t n;
3359        uint32_t registers = 0;
3360        bool wback;
3361        const uint32_t addr_byte_size = GetAddressByteSize();
3362        switch (encoding)
3363        {
3364            case eEncodingT1:
3365                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3366                n = Bits32 (opcode, 10, 8);
3367                registers = Bits32 (opcode, 7, 0);
3368                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3369                wback = BitIsClear (registers, n);
3370                // if BitCount(registers) < 1 then UNPREDICTABLE;
3371                if (BitCount(registers) < 1)
3372                    return false;
3373                break;
3374            case eEncodingT2:
3375                // if W == '1' && Rn == '1101' then SEE POP;
3376                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3377                n = Bits32 (opcode, 19, 16);
3378                registers = Bits32 (opcode, 15, 0);
3379                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3380                wback = BitIsSet (opcode, 21);
3381
3382                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3383                if ((n == 15)
3384                    || (BitCount (registers) < 2)
3385                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3386                    return false;
3387
3388                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3389                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3390                    return false;
3391
3392                // if wback && registers<n> == '1' then UNPREDICTABLE;
3393                if (wback
3394                    && BitIsSet (registers, n))
3395                    return false;
3396                break;
3397
3398            case eEncodingA1:
3399                n = Bits32 (opcode, 19, 16);
3400                registers = Bits32 (opcode, 15, 0);
3401                wback = BitIsSet (opcode, 21);
3402                if ((n == 15)
3403                    || (BitCount (registers) < 1))
3404                    return false;
3405                break;
3406            default:
3407                return false;
3408        }
3409
3410        int32_t offset = 0;
3411        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3412        if (!success)
3413            return false;
3414
3415        EmulateInstruction::Context context;
3416        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3417        RegisterInfo dwarf_reg;
3418        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3419        context.SetRegisterPlusOffset (dwarf_reg, offset);
3420
3421        for (int i = 0; i < 14; ++i)
3422        {
3423            if (BitIsSet (registers, i))
3424            {
3425                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3426                context.SetRegisterPlusOffset (dwarf_reg, offset);
3427                if (wback && (n == 13)) // Pop Instruction
3428                {
3429                    if (conditional)
3430                        context.type = EmulateInstruction::eContextRegisterLoad;
3431                    else
3432                        context.type = EmulateInstruction::eContextPopRegisterOffStack;
3433                }
3434
3435                // R[i] = MemA [address, 4]; address = address + 4;
3436                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3437                if (!success)
3438                    return false;
3439
3440                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3441                    return false;
3442
3443                offset += addr_byte_size;
3444            }
3445        }
3446
3447        if (BitIsSet (registers, 15))
3448        {
3449            //LoadWritePC (MemA [address, 4]);
3450            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3451            context.SetRegisterPlusOffset (dwarf_reg, offset);
3452            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3453            if (!success)
3454                return false;
3455            // In ARMv5T and above, this is an interworking branch.
3456            if (!LoadWritePC(context, data))
3457                return false;
3458        }
3459
3460        if (wback && BitIsClear (registers, n))
3461        {
3462            // R[n] = R[n] + 4 * BitCount (registers)
3463            int32_t offset = addr_byte_size * BitCount (registers);
3464            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3465            context.SetRegisterPlusOffset (dwarf_reg, offset);
3466
3467            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3468                return false;
3469        }
3470        if (wback && BitIsSet (registers, n))
3471            // R[n] bits(32) UNKNOWN;
3472            return WriteBits32Unknown (n);
3473    }
3474    return true;
3475}
3476
3477// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3478// The consecutive memory locations end at this address and the address just below the lowest of those locations
3479// can optionally be written back to the base register.
3480bool
3481EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3482{
3483#if 0
3484    // ARM pseudo code...
3485    if ConditionPassed() then
3486        EncodingSpecificOperations();
3487        address = R[n] - 4*BitCount(registers) + 4;
3488
3489        for i = 0 to 14
3490            if registers<i> == '1' then
3491                  R[i] = MemA[address,4]; address = address + 4;
3492
3493        if registers<15> == '1' then
3494            LoadWritePC(MemA[address,4]);
3495
3496        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3497        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3498#endif
3499
3500    bool success = false;
3501
3502    if (ConditionPassed(opcode))
3503    {
3504        uint32_t n;
3505        uint32_t registers = 0;
3506        bool wback;
3507        const uint32_t addr_byte_size = GetAddressByteSize();
3508
3509        // EncodingSpecificOperations();
3510        switch (encoding)
3511        {
3512            case eEncodingA1:
3513                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3514                n = Bits32 (opcode, 19, 16);
3515                registers = Bits32 (opcode, 15, 0);
3516                wback = BitIsSet (opcode, 21);
3517
3518                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3519                if ((n == 15) || (BitCount (registers) < 1))
3520                    return false;
3521
3522                break;
3523
3524            default:
3525                return false;
3526        }
3527        // address = R[n] - 4*BitCount(registers) + 4;
3528
3529        int32_t offset = 0;
3530        addr_t Rn = ReadCoreReg (n, &success);
3531
3532        if (!success)
3533            return false;
3534
3535        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3536
3537        EmulateInstruction::Context context;
3538        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3539        RegisterInfo dwarf_reg;
3540        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3541        context.SetRegisterPlusOffset (dwarf_reg, offset);
3542
3543        // for i = 0 to 14
3544        for (int i = 0; i < 14; ++i)
3545        {
3546            // if registers<i> == '1' then
3547            if (BitIsSet (registers, i))
3548            {
3549                  // R[i] = MemA[address,4]; address = address + 4;
3550                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3551                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3552                  if (!success)
3553                      return false;
3554                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3555                      return false;
3556                  offset += addr_byte_size;
3557            }
3558        }
3559
3560        // if registers<15> == '1' then
3561        //     LoadWritePC(MemA[address,4]);
3562        if (BitIsSet (registers, 15))
3563        {
3564            context.SetRegisterPlusOffset (dwarf_reg, offset);
3565            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3566            if (!success)
3567                return false;
3568            // In ARMv5T and above, this is an interworking branch.
3569            if (!LoadWritePC(context, data))
3570                return false;
3571        }
3572
3573        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3574        if (wback && BitIsClear (registers, n))
3575        {
3576            if (!success)
3577                return false;
3578
3579            offset = (addr_byte_size * BitCount (registers)) * -1;
3580            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3581            context.SetImmediateSigned (offset);
3582            addr_t addr = Rn + offset;
3583            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3584                return false;
3585        }
3586
3587        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3588        if (wback && BitIsSet (registers, n))
3589            return WriteBits32Unknown (n);
3590    }
3591    return true;
3592}
3593
3594// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3595// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3596// be optionally written back to the base register.
3597bool
3598EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3599{
3600#if 0
3601    // ARM pseudo code...
3602    if ConditionPassed() then
3603        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3604        address = R[n] - 4*BitCount(registers);
3605
3606        for i = 0 to 14
3607            if registers<i> == '1' then
3608                  R[i] = MemA[address,4]; address = address + 4;
3609        if registers<15> == '1' then
3610                  LoadWritePC(MemA[address,4]);
3611
3612        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3613        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3614#endif
3615
3616    bool success = false;
3617
3618    if (ConditionPassed(opcode))
3619    {
3620        uint32_t n;
3621        uint32_t registers = 0;
3622        bool wback;
3623        const uint32_t addr_byte_size = GetAddressByteSize();
3624        switch (encoding)
3625        {
3626            case eEncodingT1:
3627                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3628                n = Bits32 (opcode, 19, 16);
3629                registers = Bits32 (opcode, 15, 0);
3630                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3631                wback = BitIsSet (opcode, 21);
3632
3633                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3634                if ((n == 15)
3635                    || (BitCount (registers) < 2)
3636                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3637                    return false;
3638
3639                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3640                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3641                    return false;
3642
3643                // if wback && registers<n> == '1' then UNPREDICTABLE;
3644                if (wback && BitIsSet (registers, n))
3645                    return false;
3646
3647                break;
3648
3649            case eEncodingA1:
3650                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3651                n = Bits32 (opcode, 19, 16);
3652                registers = Bits32 (opcode, 15, 0);
3653                wback = BitIsSet (opcode, 21);
3654
3655                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3656                if ((n == 15) || (BitCount (registers) < 1))
3657                    return false;
3658
3659                break;
3660
3661            default:
3662                return false;
3663        }
3664
3665        // address = R[n] - 4*BitCount(registers);
3666
3667        int32_t offset = 0;
3668        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3669
3670        if (!success)
3671            return false;
3672
3673        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3674        EmulateInstruction::Context context;
3675        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3676        RegisterInfo dwarf_reg;
3677        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3678        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3679
3680        for (int i = 0; i < 14; ++i)
3681        {
3682            if (BitIsSet (registers, i))
3683            {
3684                // R[i] = MemA[address,4]; address = address + 4;
3685                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3686                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3687                if (!success)
3688                    return false;
3689
3690                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3691                    return false;
3692
3693                offset += addr_byte_size;
3694            }
3695        }
3696
3697        // if registers<15> == '1' then
3698        //     LoadWritePC(MemA[address,4]);
3699        if (BitIsSet (registers, 15))
3700        {
3701            context.SetRegisterPlusOffset (dwarf_reg, offset);
3702            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3703            if (!success)
3704                return false;
3705            // In ARMv5T and above, this is an interworking branch.
3706            if (!LoadWritePC(context, data))
3707                return false;
3708        }
3709
3710        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3711        if (wback && BitIsClear (registers, n))
3712        {
3713            if (!success)
3714                return false;
3715
3716            offset = (addr_byte_size * BitCount (registers)) * -1;
3717            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3718            context.SetImmediateSigned (offset);
3719            addr_t addr = Rn + offset;
3720            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3721                return false;
3722        }
3723
3724        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3725        if (wback && BitIsSet (registers, n))
3726            return WriteBits32Unknown (n);
3727    }
3728    return true;
3729}
3730
3731// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3732// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3733// optinoally be written back to the base register.
3734bool
3735EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3736{
3737#if 0
3738    if ConditionPassed() then
3739        EncodingSpecificOperations();
3740        address = R[n] + 4;
3741
3742        for i = 0 to 14
3743            if registers<i> == '1' then
3744                  R[i] = MemA[address,4]; address = address + 4;
3745        if registers<15> == '1' then
3746            LoadWritePC(MemA[address,4]);
3747
3748        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3749        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3750#endif
3751
3752    bool success = false;
3753
3754    if (ConditionPassed(opcode))
3755    {
3756        uint32_t n;
3757        uint32_t registers = 0;
3758        bool wback;
3759        const uint32_t addr_byte_size = GetAddressByteSize();
3760        switch (encoding)
3761        {
3762            case eEncodingA1:
3763                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3764                n = Bits32 (opcode, 19, 16);
3765                registers = Bits32 (opcode, 15, 0);
3766                wback = BitIsSet (opcode, 21);
3767
3768                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3769                if ((n == 15) || (BitCount (registers) < 1))
3770                    return false;
3771
3772                break;
3773            default:
3774                return false;
3775        }
3776        // address = R[n] + 4;
3777
3778        int32_t offset = 0;
3779        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3780
3781        if (!success)
3782            return false;
3783
3784        addr_t address = Rn + addr_byte_size;
3785
3786        EmulateInstruction::Context context;
3787        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3788        RegisterInfo dwarf_reg;
3789        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3790        context.SetRegisterPlusOffset (dwarf_reg, offset);
3791
3792        for (int i = 0; i < 14; ++i)
3793        {
3794            if (BitIsSet (registers, i))
3795            {
3796                // R[i] = MemA[address,4]; address = address + 4;
3797
3798                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3799                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3800                if (!success)
3801                    return false;
3802
3803                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3804                    return false;
3805
3806                offset += addr_byte_size;
3807            }
3808        }
3809
3810        // if registers<15> == '1' then
3811        //     LoadWritePC(MemA[address,4]);
3812        if (BitIsSet (registers, 15))
3813        {
3814            context.SetRegisterPlusOffset (dwarf_reg, offset);
3815            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3816            if (!success)
3817                return false;
3818            // In ARMv5T and above, this is an interworking branch.
3819            if (!LoadWritePC(context, data))
3820                return false;
3821        }
3822
3823        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3824        if (wback && BitIsClear (registers, n))
3825        {
3826            if (!success)
3827                return false;
3828
3829            offset = addr_byte_size * BitCount (registers);
3830            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3831            context.SetImmediateSigned (offset);
3832            addr_t addr = Rn + offset;
3833            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3834                return false;
3835        }
3836
3837        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3838        if (wback && BitIsSet (registers, n))
3839            return WriteBits32Unknown (n);
3840    }
3841    return true;
3842}
3843
3844// Load Register (immediate) calculates an address from a base register value and
3845// an immediate offset, loads a word from memory, and writes to a register.
3846// LDR (immediate, Thumb)
3847bool
3848EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3849{
3850#if 0
3851    // ARM pseudo code...
3852    if (ConditionPassed())
3853    {
3854        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3855        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3856        address = if index then offset_addr else R[n];
3857        data = MemU[address,4];
3858        if wback then R[n] = offset_addr;
3859        if t == 15 then
3860            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3861        elsif UnalignedSupport() || address<1:0> = '00' then
3862            R[t] = data;
3863        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3864    }
3865#endif
3866
3867    bool success = false;
3868
3869    if (ConditionPassed(opcode))
3870    {
3871        uint32_t Rt; // the destination register
3872        uint32_t Rn; // the base register
3873        uint32_t imm32; // the immediate offset used to form the address
3874        addr_t offset_addr; // the offset address
3875        addr_t address; // the calculated address
3876        uint32_t data; // the literal data value from memory load
3877        bool add, index, wback;
3878        switch (encoding) {
3879            case eEncodingT1:
3880                Rt = Bits32(opcode, 2, 0);
3881                Rn = Bits32(opcode, 5, 3);
3882                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3883                // index = TRUE; add = TRUE; wback = FALSE
3884                add = true;
3885                index = true;
3886                wback = false;
3887
3888                break;
3889
3890            case eEncodingT2:
3891                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3892                Rt = Bits32 (opcode, 10, 8);
3893                Rn = 13;
3894                imm32 = Bits32 (opcode, 7, 0) << 2;
3895
3896                // index = TRUE; add = TRUE; wback = FALSE;
3897                index = true;
3898                add = true;
3899                wback = false;
3900
3901                break;
3902
3903            case eEncodingT3:
3904                // if Rn == '1111' then SEE LDR (literal);
3905                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3906                Rt = Bits32 (opcode, 15, 12);
3907                Rn = Bits32 (opcode, 19, 16);
3908                imm32 = Bits32 (opcode, 11, 0);
3909
3910                // index = TRUE; add = TRUE; wback = FALSE;
3911                index = true;
3912                add = true;
3913                wback = false;
3914
3915                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3916                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3917                    return false;
3918
3919                break;
3920
3921            case eEncodingT4:
3922                // if Rn == '1111' then SEE LDR (literal);
3923                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3924                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3925                // if P == '0' && W == '0' then UNDEFINED;
3926                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3927                    return false;
3928
3929                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3930                Rt = Bits32 (opcode, 15, 12);
3931                Rn = Bits32 (opcode, 19, 16);
3932                imm32 = Bits32 (opcode, 7, 0);
3933
3934                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3935                index = BitIsSet (opcode, 10);
3936                add = BitIsSet (opcode, 9);
3937                wback = BitIsSet (opcode, 8);
3938
3939                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3940                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3941                    return false;
3942
3943                break;
3944
3945            default:
3946                return false;
3947        }
3948        uint32_t base = ReadCoreReg (Rn, &success);
3949        if (!success)
3950            return false;
3951        if (add)
3952            offset_addr = base + imm32;
3953        else
3954            offset_addr = base - imm32;
3955
3956        address = (index ? offset_addr : base);
3957
3958        RegisterInfo base_reg;
3959        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3960        if (wback)
3961        {
3962            EmulateInstruction::Context ctx;
3963            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3964            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3965
3966            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3967                return false;
3968        }
3969
3970        // Prepare to write to the Rt register.
3971        EmulateInstruction::Context context;
3972        context.type = EmulateInstruction::eContextRegisterLoad;
3973        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3974
3975        // Read memory from the address.
3976        data = MemURead(context, address, 4, 0, &success);
3977        if (!success)
3978            return false;
3979
3980        if (Rt == 15)
3981        {
3982            if (Bits32(address, 1, 0) == 0)
3983            {
3984                if (!LoadWritePC(context, data))
3985                    return false;
3986            }
3987            else
3988                return false;
3989        }
3990        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3991        {
3992            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3993                return false;
3994        }
3995        else
3996            WriteBits32Unknown (Rt);
3997    }
3998    return true;
3999}
4000
4001// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4002// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4003// of those locations can optionally be written back to the base register.
4004bool
4005EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4006{
4007#if 0
4008    if ConditionPassed() then
4009        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4010        address = R[n];
4011
4012        for i = 0 to 14
4013            if registers<i> == '1' then
4014                if i == n && wback && i != LowestSetBit(registers) then
4015                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4016                else
4017                    MemA[address,4] = R[i];
4018                address = address + 4;
4019
4020        if registers<15> == '1' then // Only possible for encoding A1
4021            MemA[address,4] = PCStoreValue();
4022        if wback then R[n] = R[n] + 4*BitCount(registers);
4023#endif
4024
4025    bool success = false;
4026
4027    if (ConditionPassed(opcode))
4028    {
4029        uint32_t n;
4030        uint32_t registers = 0;
4031        bool wback;
4032        const uint32_t addr_byte_size = GetAddressByteSize();
4033
4034        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4035        switch (encoding)
4036        {
4037            case eEncodingT1:
4038                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4039                n = Bits32 (opcode, 10, 8);
4040                registers = Bits32 (opcode, 7, 0);
4041                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4042                wback = true;
4043
4044                // if BitCount(registers) < 1 then UNPREDICTABLE;
4045                if (BitCount (registers) < 1)
4046                    return false;
4047
4048                break;
4049
4050            case eEncodingT2:
4051                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4052                n = Bits32 (opcode, 19, 16);
4053                registers = Bits32 (opcode, 15, 0);
4054                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4055                wback = BitIsSet (opcode, 21);
4056
4057                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4058                if ((n == 15) || (BitCount (registers) < 2))
4059                    return false;
4060
4061                // if wback && registers<n> == '1' then UNPREDICTABLE;
4062                if (wback && BitIsSet (registers, n))
4063                    return false;
4064
4065                break;
4066
4067            case eEncodingA1:
4068                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4069                n = Bits32 (opcode, 19, 16);
4070                registers = Bits32 (opcode, 15, 0);
4071                wback = BitIsSet (opcode, 21);
4072
4073                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4074                if ((n == 15) || (BitCount (registers) < 1))
4075                    return false;
4076
4077                break;
4078
4079            default:
4080                return false;
4081        }
4082
4083        // address = R[n];
4084        int32_t offset = 0;
4085        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4086        if (!success)
4087            return false;
4088
4089        EmulateInstruction::Context context;
4090        context.type = EmulateInstruction::eContextRegisterStore;
4091        RegisterInfo base_reg;
4092        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4093
4094        // for i = 0 to 14
4095        int lowest_set_bit = 14;
4096        for (int i = 0; i < 14; ++i)
4097        {
4098            // if registers<i> == '1' then
4099            if (BitIsSet (registers, i))
4100            {
4101                  if (i < lowest_set_bit)
4102                      lowest_set_bit = i;
4103                  // if i == n && wback && i != LowestSetBit(registers) then
4104                  if ((i == n) && wback && (i != lowest_set_bit))
4105                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4106                      WriteBits32UnknownToMemory (address + offset);
4107                  else
4108                  {
4109                     // MemA[address,4] = R[i];
4110                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4111                      if (!success)
4112                          return false;
4113
4114                      RegisterInfo data_reg;
4115                      GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4116                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4117                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
4118                          return false;
4119                  }
4120
4121                  // address = address + 4;
4122                  offset += addr_byte_size;
4123            }
4124        }
4125
4126        // if registers<15> == '1' then // Only possible for encoding A1
4127        //     MemA[address,4] = PCStoreValue();
4128        if (BitIsSet (registers, 15))
4129        {
4130            RegisterInfo pc_reg;
4131            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4132            context.SetRegisterPlusOffset (pc_reg, 8);
4133            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4134            if (!success)
4135                return false;
4136
4137            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4138                return false;
4139        }
4140
4141        // if wback then R[n] = R[n] + 4*BitCount(registers);
4142        if (wback)
4143        {
4144            offset = addr_byte_size * BitCount (registers);
4145            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4146            context.SetImmediateSigned (offset);
4147            addr_t data = address + offset;
4148            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4149                return false;
4150        }
4151    }
4152    return true;
4153}
4154
4155// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4156// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4157// of those locations can optionally be written back to the base register.
4158bool
4159EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4160{
4161#if 0
4162    if ConditionPassed() then
4163        EncodingSpecificOperations();
4164        address = R[n] - 4*BitCount(registers) + 4;
4165
4166        for i = 0 to 14
4167            if registers<i> == '1' then
4168                if i == n && wback && i != LowestSetBit(registers) then
4169                    MemA[address,4] = bits(32) UNKNOWN;
4170                else
4171                    MemA[address,4] = R[i];
4172                address = address + 4;
4173
4174        if registers<15> == '1' then
4175            MemA[address,4] = PCStoreValue();
4176
4177        if wback then R[n] = R[n] - 4*BitCount(registers);
4178#endif
4179
4180    bool success = false;
4181
4182    if (ConditionPassed(opcode))
4183    {
4184        uint32_t n;
4185        uint32_t registers = 0;
4186        bool wback;
4187        const uint32_t addr_byte_size = GetAddressByteSize();
4188
4189        // EncodingSpecificOperations();
4190        switch (encoding)
4191        {
4192            case eEncodingA1:
4193                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4194                n = Bits32 (opcode, 19, 16);
4195                registers = Bits32 (opcode, 15, 0);
4196                wback = BitIsSet (opcode, 21);
4197
4198                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4199                if ((n == 15) || (BitCount (registers) < 1))
4200                    return false;
4201                break;
4202            default:
4203                return false;
4204        }
4205
4206        // address = R[n] - 4*BitCount(registers) + 4;
4207        int32_t offset = 0;
4208        addr_t Rn = ReadCoreReg (n, &success);
4209        if (!success)
4210            return false;
4211
4212        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4213
4214        EmulateInstruction::Context context;
4215        context.type = EmulateInstruction::eContextRegisterStore;
4216        RegisterInfo base_reg;
4217        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4218
4219        // for i = 0 to 14
4220        int lowest_bit_set = 14;
4221        for (int i = 0; i < 14; ++i)
4222        {
4223            // if registers<i> == '1' then
4224            if (BitIsSet (registers, i))
4225            {
4226                if (i < lowest_bit_set)
4227                    lowest_bit_set = i;
4228                //if i == n && wback && i != LowestSetBit(registers) then
4229                if ((i == n) && wback && (i != lowest_bit_set))
4230                    // MemA[address,4] = bits(32) UNKNOWN;
4231                    WriteBits32UnknownToMemory (address + offset);
4232                else
4233                {
4234                    // MemA[address,4] = R[i];
4235                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4236                    if (!success)
4237                        return false;
4238
4239                    RegisterInfo data_reg;
4240                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4241                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4242                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4243                        return false;
4244                }
4245
4246                // address = address + 4;
4247                offset += addr_byte_size;
4248            }
4249        }
4250
4251        // if registers<15> == '1' then
4252        //    MemA[address,4] = PCStoreValue();
4253        if (BitIsSet (registers, 15))
4254        {
4255            RegisterInfo pc_reg;
4256            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4257            context.SetRegisterPlusOffset (pc_reg, 8);
4258            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4259            if (!success)
4260                return false;
4261
4262            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4263                return false;
4264        }
4265
4266        // if wback then R[n] = R[n] - 4*BitCount(registers);
4267        if (wback)
4268        {
4269            offset = (addr_byte_size * BitCount (registers)) * -1;
4270            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4271            context.SetImmediateSigned (offset);
4272            addr_t data = Rn + offset;
4273            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4274                return false;
4275        }
4276    }
4277    return true;
4278}
4279
4280// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4281// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4282// those locations can optionally be written back to the base register.
4283bool
4284EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4285{
4286#if 0
4287    if ConditionPassed() then
4288        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4289        address = R[n] - 4*BitCount(registers);
4290
4291        for i = 0 to 14
4292            if registers<i> == '1' then
4293                if i == n && wback && i != LowestSetBit(registers) then
4294                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4295                else
4296                    MemA[address,4] = R[i];
4297                address = address + 4;
4298
4299        if registers<15> == '1' then // Only possible for encoding A1
4300            MemA[address,4] = PCStoreValue();
4301
4302        if wback then R[n] = R[n] - 4*BitCount(registers);
4303#endif
4304
4305
4306    bool success = false;
4307
4308    if (ConditionPassed(opcode))
4309    {
4310        uint32_t n;
4311        uint32_t registers = 0;
4312        bool wback;
4313        const uint32_t addr_byte_size = GetAddressByteSize();
4314
4315        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4316        switch (encoding)
4317        {
4318            case eEncodingT1:
4319                // if W == '1' && Rn == '1101' then SEE PUSH;
4320                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4321                {
4322                    // See PUSH
4323                }
4324                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4325                n = Bits32 (opcode, 19, 16);
4326                registers = Bits32 (opcode, 15, 0);
4327                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4328                wback = BitIsSet (opcode, 21);
4329                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4330                if ((n == 15) || BitCount (registers) < 2)
4331                    return false;
4332                // if wback && registers<n> == '1' then UNPREDICTABLE;
4333                if (wback && BitIsSet (registers, n))
4334                    return false;
4335                break;
4336
4337            case eEncodingA1:
4338                // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4339                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4340                {
4341                    // See Push
4342                }
4343                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4344                n = Bits32 (opcode, 19, 16);
4345                registers = Bits32 (opcode, 15, 0);
4346                wback = BitIsSet (opcode, 21);
4347                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4348                if ((n == 15) || BitCount (registers) < 1)
4349                    return false;
4350                break;
4351
4352            default:
4353                return false;
4354        }
4355
4356        // address = R[n] - 4*BitCount(registers);
4357
4358        int32_t offset = 0;
4359        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4360        if (!success)
4361        return false;
4362
4363        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4364
4365        EmulateInstruction::Context context;
4366        context.type = EmulateInstruction::eContextRegisterStore;
4367        RegisterInfo base_reg;
4368        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4369
4370        // for i = 0 to 14
4371        uint32_t lowest_set_bit = 14;
4372        for (int i = 0; i < 14; ++i)
4373        {
4374            // if registers<i> == '1' then
4375            if (BitIsSet (registers, i))
4376            {
4377                if (i < lowest_set_bit)
4378                    lowest_set_bit = i;
4379                // if i == n && wback && i != LowestSetBit(registers) then
4380                if ((i == n) && wback && (i != lowest_set_bit))
4381                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4382                    WriteBits32UnknownToMemory (address + offset);
4383                else
4384                {
4385                    // MemA[address,4] = R[i];
4386                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4387                    if (!success)
4388                        return false;
4389
4390                    RegisterInfo data_reg;
4391                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4392                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4393                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4394                        return false;
4395                }
4396
4397                // address = address + 4;
4398                offset += addr_byte_size;
4399            }
4400        }
4401
4402        // if registers<15> == '1' then // Only possible for encoding A1
4403        //     MemA[address,4] = PCStoreValue();
4404        if (BitIsSet (registers, 15))
4405        {
4406            RegisterInfo pc_reg;
4407            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4408            context.SetRegisterPlusOffset (pc_reg, 8);
4409            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4410            if (!success)
4411                return false;
4412
4413            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4414                return false;
4415        }
4416
4417        // if wback then R[n] = R[n] - 4*BitCount(registers);
4418        if (wback)
4419        {
4420            offset = (addr_byte_size * BitCount (registers)) * -1;
4421            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4422            context.SetImmediateSigned (offset);
4423            addr_t data = Rn + offset;
4424            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4425                return false;
4426        }
4427    }
4428    return true;
4429}
4430
4431// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4432// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4433// of those locations can optionally be written back to the base register.
4434bool
4435EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4436{
4437#if 0
4438    if ConditionPassed() then
4439        EncodingSpecificOperations();
4440        address = R[n] + 4;
4441
4442        for i = 0 to 14
4443            if registers<i> == '1' then
4444                if i == n && wback && i != LowestSetBit(registers) then
4445                    MemA[address,4] = bits(32) UNKNOWN;
4446                else
4447                    MemA[address,4] = R[i];
4448                address = address + 4;
4449
4450        if registers<15> == '1' then
4451            MemA[address,4] = PCStoreValue();
4452
4453        if wback then R[n] = R[n] + 4*BitCount(registers);
4454#endif
4455
4456    bool success = false;
4457
4458    if (ConditionPassed(opcode))
4459    {
4460        uint32_t n;
4461        uint32_t registers = 0;
4462        bool wback;
4463        const uint32_t addr_byte_size = GetAddressByteSize();
4464
4465        // EncodingSpecificOperations();
4466        switch (encoding)
4467        {
4468            case eEncodingA1:
4469                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4470                n = Bits32 (opcode, 19, 16);
4471                registers = Bits32 (opcode, 15, 0);
4472                wback = BitIsSet (opcode, 21);
4473
4474                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4475                if ((n == 15) && (BitCount (registers) < 1))
4476                    return false;
4477                break;
4478            default:
4479                return false;
4480        }
4481        // address = R[n] + 4;
4482
4483        int32_t offset = 0;
4484        addr_t Rn = ReadCoreReg (n, &success);
4485        if (!success)
4486            return false;
4487
4488        addr_t address = Rn + addr_byte_size;
4489
4490        EmulateInstruction::Context context;
4491        context.type = EmulateInstruction::eContextRegisterStore;
4492        RegisterInfo base_reg;
4493        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4494
4495        uint32_t lowest_set_bit = 14;
4496        // for i = 0 to 14
4497        for (int i = 0; i < 14; ++i)
4498        {
4499            // if registers<i> == '1' then
4500            if (BitIsSet (registers, i))
4501            {
4502                if (i < lowest_set_bit)
4503                    lowest_set_bit = i;
4504                // if i == n && wback && i != LowestSetBit(registers) then
4505                if ((i == n) && wback && (i != lowest_set_bit))
4506                    // MemA[address,4] = bits(32) UNKNOWN;
4507                    WriteBits32UnknownToMemory (address + offset);
4508                // else
4509                else
4510                {
4511                    // MemA[address,4] = R[i];
4512                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4513                    if (!success)
4514                        return false;
4515
4516                    RegisterInfo data_reg;
4517                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4518                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4519                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4520                        return false;
4521                }
4522
4523                // address = address + 4;
4524                offset += addr_byte_size;
4525            }
4526        }
4527
4528        // if registers<15> == '1' then
4529            // MemA[address,4] = PCStoreValue();
4530        if (BitIsSet (registers, 15))
4531        {
4532            RegisterInfo pc_reg;
4533            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4534            context.SetRegisterPlusOffset (pc_reg, 8);
4535            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4536            if (!success)
4537            return false;
4538
4539            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4540                return false;
4541        }
4542
4543        // if wback then R[n] = R[n] + 4*BitCount(registers);
4544        if (wback)
4545        {
4546            offset = addr_byte_size * BitCount (registers);
4547            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4548            context.SetImmediateSigned (offset);
4549            addr_t data = Rn + offset;
4550            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4551                return false;
4552        }
4553    }
4554    return true;
4555}
4556
4557// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4558// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4559bool
4560EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4561{
4562#if 0
4563    if ConditionPassed() then
4564        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4565        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4566        address = if index then offset_addr else R[n];
4567        if UnalignedSupport() || address<1:0> == '00' then
4568            MemU[address,4] = R[t];
4569        else // Can only occur before ARMv7
4570            MemU[address,4] = bits(32) UNKNOWN;
4571        if wback then R[n] = offset_addr;
4572#endif
4573
4574    bool success = false;
4575
4576    if (ConditionPassed(opcode))
4577    {
4578        const uint32_t addr_byte_size = GetAddressByteSize();
4579
4580        uint32_t t;
4581        uint32_t n;
4582        uint32_t imm32;
4583        bool index;
4584        bool add;
4585        bool wback;
4586        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4587        switch (encoding)
4588        {
4589            case eEncodingT1:
4590                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4591                t = Bits32 (opcode, 2, 0);
4592                n = Bits32 (opcode, 5, 3);
4593                imm32 = Bits32 (opcode, 10, 6) << 2;
4594
4595                // index = TRUE; add = TRUE; wback = FALSE;
4596                index = true;
4597                add = false;
4598                wback = false;
4599                break;
4600
4601            case eEncodingT2:
4602                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4603                t = Bits32 (opcode, 10, 8);
4604                n = 13;
4605                imm32 = Bits32 (opcode, 7, 0) << 2;
4606
4607                // index = TRUE; add = TRUE; wback = FALSE;
4608                index = true;
4609                add = true;
4610                wback = false;
4611                break;
4612
4613            case eEncodingT3:
4614                // if Rn == '1111' then UNDEFINED;
4615                if (Bits32 (opcode, 19, 16) == 15)
4616                    return false;
4617
4618                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4619                t = Bits32 (opcode, 15, 12);
4620                n = Bits32 (opcode, 19, 16);
4621                imm32 = Bits32 (opcode, 11, 0);
4622
4623                // index = TRUE; add = TRUE; wback = FALSE;
4624                index = true;
4625                add = true;
4626                wback = false;
4627
4628                // if t == 15 then UNPREDICTABLE;
4629                if (t == 15)
4630                    return false;
4631                break;
4632
4633            case eEncodingT4:
4634                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4635                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4636                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4637                if ((Bits32 (opcode, 19, 16) == 15)
4638                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4639                    return false;
4640
4641                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4642                t = Bits32 (opcode, 15, 12);
4643                n = Bits32 (opcode, 19, 16);
4644                imm32 = Bits32 (opcode, 7, 0);
4645
4646                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4647                index = BitIsSet (opcode, 10);
4648                add = BitIsSet (opcode, 9);
4649                wback = BitIsSet (opcode, 8);
4650
4651                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4652                if ((t == 15) || (wback && (n == t)))
4653                    return false;
4654                break;
4655
4656            default:
4657                return false;
4658        }
4659
4660        addr_t offset_addr;
4661        addr_t address;
4662
4663        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4664        uint32_t base_address = ReadCoreReg (n, &success);
4665        if (!success)
4666            return false;
4667
4668        if (add)
4669            offset_addr = base_address + imm32;
4670        else
4671            offset_addr = base_address - imm32;
4672
4673        // address = if index then offset_addr else R[n];
4674        if (index)
4675            address = offset_addr;
4676        else
4677            address = base_address;
4678
4679        EmulateInstruction::Context context;
4680        context.type = eContextRegisterStore;
4681        RegisterInfo base_reg;
4682        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4683
4684        // if UnalignedSupport() || address<1:0> == '00' then
4685        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4686        {
4687            // MemU[address,4] = R[t];
4688            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4689            if (!success)
4690                return false;
4691
4692            RegisterInfo data_reg;
4693            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4694            int32_t offset = address - base_address;
4695            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4696            if (!MemUWrite (context, address, data, addr_byte_size))
4697                return false;
4698        }
4699        else
4700        {
4701            // MemU[address,4] = bits(32) UNKNOWN;
4702            WriteBits32UnknownToMemory (address);
4703        }
4704
4705        // if wback then R[n] = offset_addr;
4706        if (wback)
4707        {
4708            context.type = eContextRegisterLoad;
4709            context.SetAddress (offset_addr);
4710            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4711                return false;
4712        }
4713    }
4714    return true;
4715}
4716
4717// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4718// word from a register to memory.   The offset register value can optionally be shifted.
4719bool
4720EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4721{
4722#if 0
4723    if ConditionPassed() then
4724        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4725        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4726        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4727        address = if index then offset_addr else R[n];
4728        if t == 15 then // Only possible for encoding A1
4729            data = PCStoreValue();
4730        else
4731            data = R[t];
4732        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4733            MemU[address,4] = data;
4734        else // Can only occur before ARMv7
4735            MemU[address,4] = bits(32) UNKNOWN;
4736        if wback then R[n] = offset_addr;
4737#endif
4738
4739    bool success = false;
4740
4741    if (ConditionPassed(opcode))
4742    {
4743        const uint32_t addr_byte_size = GetAddressByteSize();
4744
4745        uint32_t t;
4746        uint32_t n;
4747        uint32_t m;
4748        ARM_ShifterType shift_t;
4749        uint32_t shift_n;
4750        bool index;
4751        bool add;
4752        bool wback;
4753
4754        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4755        switch (encoding)
4756        {
4757            case eEncodingT1:
4758                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4759                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4760                t = Bits32 (opcode, 2, 0);
4761                n = Bits32 (opcode, 5, 3);
4762                m = Bits32 (opcode, 8, 6);
4763
4764                // index = TRUE; add = TRUE; wback = FALSE;
4765                index = true;
4766                add = true;
4767                wback = false;
4768
4769                // (shift_t, shift_n) = (SRType_LSL, 0);
4770                shift_t = SRType_LSL;
4771                shift_n = 0;
4772                break;
4773
4774            case eEncodingT2:
4775                // if Rn == '1111' then UNDEFINED;
4776                if (Bits32 (opcode, 19, 16) == 15)
4777                    return false;
4778
4779                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4780                t = Bits32 (opcode, 15, 12);
4781                n = Bits32 (opcode, 19, 16);
4782                m = Bits32 (opcode, 3, 0);
4783
4784                // index = TRUE; add = TRUE; wback = FALSE;
4785                index = true;
4786                add = true;
4787                wback = false;
4788
4789                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4790                shift_t = SRType_LSL;
4791                shift_n = Bits32 (opcode, 5, 4);
4792
4793                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4794                if ((t == 15) || (BadReg (m)))
4795                    return false;
4796                break;
4797
4798            case eEncodingA1:
4799            {
4800                // if P == '0' && W == '1' then SEE STRT;
4801                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4802                t = Bits32 (opcode, 15, 12);
4803                n = Bits32 (opcode, 19, 16);
4804                m = Bits32 (opcode, 3, 0);
4805
4806                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4807                index = BitIsSet (opcode, 24);
4808                add = BitIsSet (opcode, 23);
4809                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4810
4811                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4812                uint32_t typ = Bits32 (opcode, 6, 5);
4813                uint32_t imm5 = Bits32 (opcode, 11, 7);
4814                shift_n = DecodeImmShift(typ, imm5, shift_t);
4815
4816                // if m == 15 then UNPREDICTABLE;
4817                if (m == 15)
4818                    return false;
4819
4820                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4821                if (wback && ((n == 15) || (n == t)))
4822                    return false;
4823
4824                break;
4825            }
4826            default:
4827                return false;
4828        }
4829
4830        addr_t offset_addr;
4831        addr_t address;
4832        int32_t offset = 0;
4833
4834        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4835        if (!success)
4836            return false;
4837
4838        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4839        if (!success)
4840            return false;
4841
4842        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4843        offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4844        if (!success)
4845            return false;
4846
4847        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4848        if (add)
4849            offset_addr = base_address + offset;
4850        else
4851            offset_addr = base_address - offset;
4852
4853        // address = if index then offset_addr else R[n];
4854        if (index)
4855            address = offset_addr;
4856        else
4857            address = base_address;
4858
4859        uint32_t data;
4860        // if t == 15 then // Only possible for encoding A1
4861        if (t == 15)
4862            // data = PCStoreValue();
4863            data = ReadCoreReg (PC_REG, &success);
4864        else
4865            // data = R[t];
4866            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4867
4868        if (!success)
4869            return false;
4870
4871        EmulateInstruction::Context context;
4872        context.type = eContextRegisterStore;
4873
4874        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4875        if (UnalignedSupport ()
4876            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4877            || CurrentInstrSet() == eModeARM)
4878        {
4879            // MemU[address,4] = data;
4880
4881            RegisterInfo base_reg;
4882            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4883
4884            RegisterInfo data_reg;
4885            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4886
4887            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4888            if (!MemUWrite (context, address, data, addr_byte_size))
4889                return false;
4890
4891        }
4892        else
4893            // MemU[address,4] = bits(32) UNKNOWN;
4894            WriteBits32UnknownToMemory (address);
4895
4896        // if wback then R[n] = offset_addr;
4897        if (wback)
4898        {
4899            context.type = eContextRegisterLoad;
4900            context.SetAddress (offset_addr);
4901            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4902                return false;
4903        }
4904
4905    }
4906    return true;
4907}
4908
4909bool
4910EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4911{
4912#if 0
4913    if ConditionPassed() then
4914        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4915        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4916        address = if index then offset_addr else R[n];
4917        MemU[address,1] = R[t]<7:0>;
4918        if wback then R[n] = offset_addr;
4919#endif
4920
4921
4922    bool success = false;
4923
4924    if (ConditionPassed(opcode))
4925    {
4926        uint32_t t;
4927        uint32_t n;
4928        uint32_t imm32;
4929        bool index;
4930        bool add;
4931        bool wback;
4932        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4933        switch (encoding)
4934        {
4935            case eEncodingT1:
4936                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4937                t = Bits32 (opcode, 2, 0);
4938                n = Bits32 (opcode, 5, 3);
4939                imm32 = Bits32 (opcode, 10, 6);
4940
4941                // index = TRUE; add = TRUE; wback = FALSE;
4942                index = true;
4943                add = true;
4944                wback = false;
4945                break;
4946
4947            case eEncodingT2:
4948                // if Rn == '1111' then UNDEFINED;
4949                if (Bits32 (opcode, 19, 16) == 15)
4950                    return false;
4951
4952                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4953                t = Bits32 (opcode, 15, 12);
4954                n = Bits32 (opcode, 19, 16);
4955                imm32 = Bits32 (opcode, 11, 0);
4956
4957                // index = TRUE; add = TRUE; wback = FALSE;
4958                index = true;
4959                add = true;
4960                wback = false;
4961
4962                // if BadReg(t) then UNPREDICTABLE;
4963                if (BadReg (t))
4964                    return false;
4965                break;
4966
4967            case eEncodingT3:
4968                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4969                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4970                if (Bits32 (opcode, 19, 16) == 15)
4971                    return false;
4972
4973                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4974                t = Bits32 (opcode, 15, 12);
4975                n = Bits32 (opcode, 19, 16);
4976                imm32 = Bits32 (opcode, 7, 0);
4977
4978                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4979                index = BitIsSet (opcode, 10);
4980                add = BitIsSet (opcode, 9);
4981                wback = BitIsSet (opcode, 8);
4982
4983                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4984                if ((BadReg (t)) || (wback && (n == t)))
4985                    return false;
4986                break;
4987
4988            default:
4989                return false;
4990        }
4991
4992        addr_t offset_addr;
4993        addr_t address;
4994        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4995        if (!success)
4996            return false;
4997
4998        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4999        if (add)
5000            offset_addr = base_address + imm32;
5001        else
5002            offset_addr = base_address - imm32;
5003
5004        // address = if index then offset_addr else R[n];
5005        if (index)
5006            address = offset_addr;
5007        else
5008            address = base_address;
5009
5010        // MemU[address,1] = R[t]<7:0>
5011        RegisterInfo base_reg;
5012        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5013
5014        RegisterInfo data_reg;
5015        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5016
5017        EmulateInstruction::Context context;
5018        context.type = eContextRegisterStore;
5019        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5020
5021        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5022        if (!success)
5023            return false;
5024
5025        data = Bits32 (data, 7, 0);
5026
5027        if (!MemUWrite (context, address, data, 1))
5028            return false;
5029
5030        // if wback then R[n] = offset_addr;
5031        if (wback)
5032        {
5033            context.type = eContextRegisterLoad;
5034            context.SetAddress (offset_addr);
5035            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5036                return false;
5037        }
5038
5039    }
5040
5041    return true;
5042}
5043
5044// STRH (register) calculates an address from a base register value and an offset register value, and stores a
5045// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5046bool
5047EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5048{
5049#if 0
5050    if ConditionPassed() then
5051        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5052        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5053        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5054        address = if index then offset_addr else R[n];
5055        if UnalignedSupport() || address<0> == '0' then
5056            MemU[address,2] = R[t]<15:0>;
5057        else // Can only occur before ARMv7
5058            MemU[address,2] = bits(16) UNKNOWN;
5059        if wback then R[n] = offset_addr;
5060#endif
5061
5062    bool success = false;
5063
5064    if (ConditionPassed(opcode))
5065    {
5066        uint32_t t;
5067        uint32_t n;
5068        uint32_t m;
5069        bool index;
5070        bool add;
5071        bool wback;
5072        ARM_ShifterType shift_t;
5073        uint32_t shift_n;
5074
5075        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5076        switch (encoding)
5077        {
5078            case eEncodingT1:
5079                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5080                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5081                t = Bits32 (opcode, 2, 0);
5082                n = Bits32 (opcode, 5, 3);
5083                m = Bits32 (opcode, 8, 6);
5084
5085                // index = TRUE; add = TRUE; wback = FALSE;
5086                index = true;
5087                add = true;
5088                wback = false;
5089
5090                // (shift_t, shift_n) = (SRType_LSL, 0);
5091                shift_t = SRType_LSL;
5092                shift_n = 0;
5093
5094                break;
5095
5096            case eEncodingT2:
5097                // if Rn == '1111' then UNDEFINED;
5098                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5099                t = Bits32 (opcode, 15, 12);
5100                n = Bits32 (opcode, 19, 16);
5101                m = Bits32 (opcode, 3, 0);
5102                if (n == 15)
5103                    return false;
5104
5105                // index = TRUE; add = TRUE; wback = FALSE;
5106                index = true;
5107                add = true;
5108                wback = false;
5109
5110                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5111                shift_t = SRType_LSL;
5112                shift_n = Bits32 (opcode, 5, 4);
5113
5114                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5115                if (BadReg (t) || BadReg (m))
5116                    return false;
5117
5118                break;
5119
5120            case eEncodingA1:
5121                // if P == '0' && W == '1' then SEE STRHT;
5122                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5123                t = Bits32 (opcode, 15, 12);
5124                n = Bits32 (opcode, 19, 16);
5125                m = Bits32 (opcode, 3, 0);
5126
5127                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5128                index = BitIsSet (opcode, 24);
5129                add = BitIsSet (opcode, 23);
5130                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5131
5132                // (shift_t, shift_n) = (SRType_LSL, 0);
5133                shift_t = SRType_LSL;
5134                shift_n = 0;
5135
5136                // if t == 15 || m == 15 then UNPREDICTABLE;
5137                if ((t == 15) || (m == 15))
5138                    return false;
5139
5140                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5141                if (wback && ((n == 15) || (n == t)))
5142                    return false;
5143
5144                break;
5145
5146            default:
5147                return false;
5148        }
5149
5150        uint32_t Rm = ReadCoreReg (m, &success);
5151        if (!success)
5152            return false;
5153
5154        uint32_t Rn = ReadCoreReg (n, &success);
5155        if (!success)
5156            return false;
5157
5158        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5159        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5160        if (!success)
5161            return false;
5162
5163        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5164        addr_t offset_addr;
5165        if (add)
5166            offset_addr = Rn + offset;
5167        else
5168            offset_addr = Rn - offset;
5169
5170        // address = if index then offset_addr else R[n];
5171        addr_t address;
5172        if (index)
5173            address = offset_addr;
5174        else
5175            address = Rn;
5176
5177        EmulateInstruction::Context context;
5178        context.type = eContextRegisterStore;
5179        RegisterInfo base_reg;
5180        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5181        RegisterInfo offset_reg;
5182        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5183
5184        // if UnalignedSupport() || address<0> == '0' then
5185        if (UnalignedSupport() || BitIsClear (address, 0))
5186        {
5187            // MemU[address,2] = R[t]<15:0>;
5188            uint32_t Rt = ReadCoreReg (t, &success);
5189            if (!success)
5190                return false;
5191
5192            EmulateInstruction::Context context;
5193            context.type = eContextRegisterStore;
5194            RegisterInfo base_reg;
5195            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5196            RegisterInfo offset_reg;
5197            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5198            RegisterInfo data_reg;
5199            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5200            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5201
5202            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5203                return false;
5204        }
5205        else // Can only occur before ARMv7
5206        {
5207            // MemU[address,2] = bits(16) UNKNOWN;
5208        }
5209
5210        // if wback then R[n] = offset_addr;
5211        if (wback)
5212        {
5213            context.type = eContextAdjustBaseRegister;
5214            context.SetAddress (offset_addr);
5215            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5216                return false;
5217        }
5218    }
5219
5220    return true;
5221}
5222
5223// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5224// and writes the result to the destination register.  It can optionally update the condition flags
5225// based on the result.
5226bool
5227EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5228{
5229#if 0
5230    // ARM pseudo code...
5231    if ConditionPassed() then
5232        EncodingSpecificOperations();
5233        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5234        if d == 15 then         // Can only occur for ARM encoding
5235            ALUWritePC(result); // setflags is always FALSE here
5236        else
5237            R[d] = result;
5238            if setflags then
5239                APSR.N = result<31>;
5240                APSR.Z = IsZeroBit(result);
5241                APSR.C = carry;
5242                APSR.V = overflow;
5243#endif
5244
5245    bool success = false;
5246
5247    if (ConditionPassed(opcode))
5248    {
5249        uint32_t Rd, Rn;
5250        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5251        bool setflags;
5252        switch (encoding)
5253        {
5254        case eEncodingT1:
5255            Rd = Bits32(opcode, 11, 8);
5256            Rn = Bits32(opcode, 19, 16);
5257            setflags = BitIsSet(opcode, 20);
5258            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5259            if (BadReg(Rd) || BadReg(Rn))
5260                return false;
5261            break;
5262        case eEncodingA1:
5263            Rd = Bits32(opcode, 15, 12);
5264            Rn = Bits32(opcode, 19, 16);
5265            setflags = BitIsSet(opcode, 20);
5266            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5267
5268            if (Rd == 15 && setflags)
5269                return EmulateSUBSPcLrEtc (opcode, encoding);
5270            break;
5271        default:
5272            return false;
5273        }
5274
5275        // Read the first operand.
5276        int32_t val1 = ReadCoreReg(Rn, &success);
5277        if (!success)
5278            return false;
5279
5280        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5281
5282        EmulateInstruction::Context context;
5283        context.type = EmulateInstruction::eContextImmediate;
5284        context.SetNoArgs ();
5285
5286        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5287            return false;
5288    }
5289    return true;
5290}
5291
5292// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5293// register value, and writes the result to the destination register.  It can optionally update the
5294// condition flags based on the result.
5295bool
5296EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5297{
5298#if 0
5299    // ARM pseudo code...
5300    if ConditionPassed() then
5301        EncodingSpecificOperations();
5302        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5303        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5304        if d == 15 then         // Can only occur for ARM encoding
5305            ALUWritePC(result); // setflags is always FALSE here
5306        else
5307            R[d] = result;
5308            if setflags then
5309                APSR.N = result<31>;
5310                APSR.Z = IsZeroBit(result);
5311                APSR.C = carry;
5312                APSR.V = overflow;
5313#endif
5314
5315    bool success = false;
5316
5317    if (ConditionPassed(opcode))
5318    {
5319        uint32_t Rd, Rn, Rm;
5320        ARM_ShifterType shift_t;
5321        uint32_t shift_n; // the shift applied to the value read from Rm
5322        bool setflags;
5323        switch (encoding)
5324        {
5325        case eEncodingT1:
5326            Rd = Rn = Bits32(opcode, 2, 0);
5327            Rm = Bits32(opcode, 5, 3);
5328            setflags = !InITBlock();
5329            shift_t = SRType_LSL;
5330            shift_n = 0;
5331            break;
5332        case eEncodingT2:
5333            Rd = Bits32(opcode, 11, 8);
5334            Rn = Bits32(opcode, 19, 16);
5335            Rm = Bits32(opcode, 3, 0);
5336            setflags = BitIsSet(opcode, 20);
5337            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5338            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5339                return false;
5340            break;
5341        case eEncodingA1:
5342            Rd = Bits32(opcode, 15, 12);
5343            Rn = Bits32(opcode, 19, 16);
5344            Rm = Bits32(opcode, 3, 0);
5345            setflags = BitIsSet(opcode, 20);
5346            shift_n = DecodeImmShiftARM(opcode, shift_t);
5347
5348            if (Rd == 15 && setflags)
5349                return EmulateSUBSPcLrEtc (opcode, encoding);
5350            break;
5351        default:
5352            return false;
5353        }
5354
5355        // Read the first operand.
5356        int32_t val1 = ReadCoreReg(Rn, &success);
5357        if (!success)
5358            return false;
5359
5360        // Read the second operand.
5361        int32_t val2 = ReadCoreReg(Rm, &success);
5362        if (!success)
5363            return false;
5364
5365        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5366        if (!success)
5367            return false;
5368        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5369
5370        EmulateInstruction::Context context;
5371        context.type = EmulateInstruction::eContextImmediate;
5372        context.SetNoArgs ();
5373
5374        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5375            return false;
5376    }
5377    return true;
5378}
5379
5380// This instruction adds an immediate value to the PC value to form a PC-relative address,
5381// and writes the result to the destination register.
5382bool
5383EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5384{
5385#if 0
5386    // ARM pseudo code...
5387    if ConditionPassed() then
5388        EncodingSpecificOperations();
5389        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5390        if d == 15 then         // Can only occur for ARM encodings
5391            ALUWritePC(result);
5392        else
5393            R[d] = result;
5394#endif
5395
5396    bool success = false;
5397
5398    if (ConditionPassed(opcode))
5399    {
5400        uint32_t Rd;
5401        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5402        bool add;
5403        switch (encoding)
5404        {
5405        case eEncodingT1:
5406            Rd = Bits32(opcode, 10, 8);
5407            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5408            add = true;
5409            break;
5410        case eEncodingT2:
5411        case eEncodingT3:
5412            Rd = Bits32(opcode, 11, 8);
5413            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5414            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5415            if (BadReg(Rd))
5416                return false;
5417            break;
5418        case eEncodingA1:
5419        case eEncodingA2:
5420            Rd = Bits32(opcode, 15, 12);
5421            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5422            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5423            break;
5424        default:
5425            return false;
5426        }
5427
5428        // Read the PC value.
5429        uint32_t pc = ReadCoreReg(PC_REG, &success);
5430        if (!success)
5431            return false;
5432
5433        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5434
5435        EmulateInstruction::Context context;
5436        context.type = EmulateInstruction::eContextImmediate;
5437        context.SetNoArgs ();
5438
5439        if (!WriteCoreReg(context, result, Rd))
5440            return false;
5441    }
5442    return true;
5443}
5444
5445// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5446// to the destination register.  It can optionally update the condition flags based on the result.
5447bool
5448EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5449{
5450#if 0
5451    // ARM pseudo code...
5452    if ConditionPassed() then
5453        EncodingSpecificOperations();
5454        result = R[n] AND imm32;
5455        if d == 15 then         // Can only occur for ARM encoding
5456            ALUWritePC(result); // setflags is always FALSE here
5457        else
5458            R[d] = result;
5459            if setflags then
5460                APSR.N = result<31>;
5461                APSR.Z = IsZeroBit(result);
5462                APSR.C = carry;
5463                // APSR.V unchanged
5464#endif
5465
5466    bool success = false;
5467
5468    if (ConditionPassed(opcode))
5469    {
5470        uint32_t Rd, Rn;
5471        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5472        bool setflags;
5473        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5474        switch (encoding)
5475        {
5476        case eEncodingT1:
5477            Rd = Bits32(opcode, 11, 8);
5478            Rn = Bits32(opcode, 19, 16);
5479            setflags = BitIsSet(opcode, 20);
5480            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5481            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5482            if (Rd == 15 && setflags)
5483                return EmulateTSTImm(opcode, eEncodingT1);
5484            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5485                return false;
5486            break;
5487        case eEncodingA1:
5488            Rd = Bits32(opcode, 15, 12);
5489            Rn = Bits32(opcode, 19, 16);
5490            setflags = BitIsSet(opcode, 20);
5491            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5492
5493            if (Rd == 15 && setflags)
5494                return EmulateSUBSPcLrEtc (opcode, encoding);
5495            break;
5496        default:
5497            return false;
5498        }
5499
5500        // Read the first operand.
5501        uint32_t val1 = ReadCoreReg(Rn, &success);
5502        if (!success)
5503            return false;
5504
5505        uint32_t result = val1 & imm32;
5506
5507        EmulateInstruction::Context context;
5508        context.type = EmulateInstruction::eContextImmediate;
5509        context.SetNoArgs ();
5510
5511        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5512            return false;
5513    }
5514    return true;
5515}
5516
5517// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5518// and writes the result to the destination register.  It can optionally update the condition flags
5519// based on the result.
5520bool
5521EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5522{
5523#if 0
5524    // ARM pseudo code...
5525    if ConditionPassed() then
5526        EncodingSpecificOperations();
5527        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5528        result = R[n] AND shifted;
5529        if d == 15 then         // Can only occur for ARM encoding
5530            ALUWritePC(result); // setflags is always FALSE here
5531        else
5532            R[d] = result;
5533            if setflags then
5534                APSR.N = result<31>;
5535                APSR.Z = IsZeroBit(result);
5536                APSR.C = carry;
5537                // APSR.V unchanged
5538#endif
5539
5540    bool success = false;
5541
5542    if (ConditionPassed(opcode))
5543    {
5544        uint32_t Rd, Rn, Rm;
5545        ARM_ShifterType shift_t;
5546        uint32_t shift_n; // the shift applied to the value read from Rm
5547        bool setflags;
5548        uint32_t carry;
5549        switch (encoding)
5550        {
5551        case eEncodingT1:
5552            Rd = Rn = Bits32(opcode, 2, 0);
5553            Rm = Bits32(opcode, 5, 3);
5554            setflags = !InITBlock();
5555            shift_t = SRType_LSL;
5556            shift_n = 0;
5557            break;
5558        case eEncodingT2:
5559            Rd = Bits32(opcode, 11, 8);
5560            Rn = Bits32(opcode, 19, 16);
5561            Rm = Bits32(opcode, 3, 0);
5562            setflags = BitIsSet(opcode, 20);
5563            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5564            // if Rd == '1111' && S == '1' then SEE TST (register);
5565            if (Rd == 15 && setflags)
5566                return EmulateTSTReg(opcode, eEncodingT2);
5567            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5568                return false;
5569            break;
5570        case eEncodingA1:
5571            Rd = Bits32(opcode, 15, 12);
5572            Rn = Bits32(opcode, 19, 16);
5573            Rm = Bits32(opcode, 3, 0);
5574            setflags = BitIsSet(opcode, 20);
5575            shift_n = DecodeImmShiftARM(opcode, shift_t);
5576
5577            if (Rd == 15 && setflags)
5578                return EmulateSUBSPcLrEtc (opcode, encoding);
5579            break;
5580        default:
5581            return false;
5582        }
5583
5584        // Read the first operand.
5585        uint32_t val1 = ReadCoreReg(Rn, &success);
5586        if (!success)
5587            return false;
5588
5589        // Read the second operand.
5590        uint32_t val2 = ReadCoreReg(Rm, &success);
5591        if (!success)
5592            return false;
5593
5594        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5595        if (!success)
5596            return false;
5597        uint32_t result = val1 & shifted;
5598
5599        EmulateInstruction::Context context;
5600        context.type = EmulateInstruction::eContextImmediate;
5601        context.SetNoArgs ();
5602
5603        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5604            return false;
5605    }
5606    return true;
5607}
5608
5609// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5610// immediate value, and writes the result to the destination register.  It can optionally update the
5611// condition flags based on the result.
5612bool
5613EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5614{
5615#if 0
5616    // ARM pseudo code...
5617    if ConditionPassed() then
5618        EncodingSpecificOperations();
5619        result = R[n] AND NOT(imm32);
5620        if d == 15 then         // Can only occur for ARM encoding
5621            ALUWritePC(result); // setflags is always FALSE here
5622        else
5623            R[d] = result;
5624            if setflags then
5625                APSR.N = result<31>;
5626                APSR.Z = IsZeroBit(result);
5627                APSR.C = carry;
5628                // APSR.V unchanged
5629#endif
5630
5631    bool success = false;
5632
5633    if (ConditionPassed(opcode))
5634    {
5635        uint32_t Rd, Rn;
5636        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5637        bool setflags;
5638        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5639        switch (encoding)
5640        {
5641        case eEncodingT1:
5642            Rd = Bits32(opcode, 11, 8);
5643            Rn = Bits32(opcode, 19, 16);
5644            setflags = BitIsSet(opcode, 20);
5645            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5646            if (BadReg(Rd) || BadReg(Rn))
5647                return false;
5648            break;
5649        case eEncodingA1:
5650            Rd = Bits32(opcode, 15, 12);
5651            Rn = Bits32(opcode, 19, 16);
5652            setflags = BitIsSet(opcode, 20);
5653            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5654
5655            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5656            if (Rd == 15 && setflags)
5657                return EmulateSUBSPcLrEtc (opcode, encoding);
5658            break;
5659        default:
5660            return false;
5661        }
5662
5663        // Read the first operand.
5664        uint32_t val1 = ReadCoreReg(Rn, &success);
5665        if (!success)
5666            return false;
5667
5668        uint32_t result = val1 & ~imm32;
5669
5670        EmulateInstruction::Context context;
5671        context.type = EmulateInstruction::eContextImmediate;
5672        context.SetNoArgs ();
5673
5674        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5675            return false;
5676    }
5677    return true;
5678}
5679
5680// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5681// optionally-shifted register value, and writes the result to the destination register.
5682// It can optionally update the condition flags based on the result.
5683bool
5684EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5685{
5686#if 0
5687    // ARM pseudo code...
5688    if ConditionPassed() then
5689        EncodingSpecificOperations();
5690        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5691        result = R[n] AND NOT(shifted);
5692        if d == 15 then         // Can only occur for ARM encoding
5693            ALUWritePC(result); // setflags is always FALSE here
5694        else
5695            R[d] = result;
5696            if setflags then
5697                APSR.N = result<31>;
5698                APSR.Z = IsZeroBit(result);
5699                APSR.C = carry;
5700                // APSR.V unchanged
5701#endif
5702
5703    bool success = false;
5704
5705    if (ConditionPassed(opcode))
5706    {
5707        uint32_t Rd, Rn, Rm;
5708        ARM_ShifterType shift_t;
5709        uint32_t shift_n; // the shift applied to the value read from Rm
5710        bool setflags;
5711        uint32_t carry;
5712        switch (encoding)
5713        {
5714        case eEncodingT1:
5715            Rd = Rn = Bits32(opcode, 2, 0);
5716            Rm = Bits32(opcode, 5, 3);
5717            setflags = !InITBlock();
5718            shift_t = SRType_LSL;
5719            shift_n = 0;
5720            break;
5721        case eEncodingT2:
5722            Rd = Bits32(opcode, 11, 8);
5723            Rn = Bits32(opcode, 19, 16);
5724            Rm = Bits32(opcode, 3, 0);
5725            setflags = BitIsSet(opcode, 20);
5726            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5727            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5728                return false;
5729            break;
5730        case eEncodingA1:
5731            Rd = Bits32(opcode, 15, 12);
5732            Rn = Bits32(opcode, 19, 16);
5733            Rm = Bits32(opcode, 3, 0);
5734            setflags = BitIsSet(opcode, 20);
5735            shift_n = DecodeImmShiftARM(opcode, shift_t);
5736
5737            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5738            if (Rd == 15 && setflags)
5739                return EmulateSUBSPcLrEtc (opcode, encoding);
5740            break;
5741        default:
5742            return false;
5743        }
5744
5745        // Read the first operand.
5746        uint32_t val1 = ReadCoreReg(Rn, &success);
5747        if (!success)
5748            return false;
5749
5750        // Read the second operand.
5751        uint32_t val2 = ReadCoreReg(Rm, &success);
5752        if (!success)
5753            return false;
5754
5755        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5756        if (!success)
5757            return false;
5758        uint32_t result = val1 & ~shifted;
5759
5760        EmulateInstruction::Context context;
5761        context.type = EmulateInstruction::eContextImmediate;
5762        context.SetNoArgs ();
5763
5764        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5765            return false;
5766    }
5767    return true;
5768}
5769
5770// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5771// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5772bool
5773EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5774{
5775#if 0
5776    if ConditionPassed() then
5777        EncodingSpecificOperations();
5778        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5779        address = if index then offset_addr else R[n];
5780        data = MemU[address,4];
5781        if wback then R[n] = offset_addr;
5782        if t == 15 then
5783            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5784        elsif UnalignedSupport() || address<1:0> = '00' then
5785            R[t] = data;
5786        else // Can only apply before ARMv7
5787            R[t] = ROR(data, 8*UInt(address<1:0>));
5788#endif
5789
5790    bool success = false;
5791
5792    if (ConditionPassed(opcode))
5793    {
5794        const uint32_t addr_byte_size = GetAddressByteSize();
5795
5796        uint32_t t;
5797        uint32_t n;
5798        uint32_t imm32;
5799        bool index;
5800        bool add;
5801        bool wback;
5802
5803        switch (encoding)
5804        {
5805            case eEncodingA1:
5806                // if Rn == '1111' then SEE LDR (literal);
5807                // if P == '0' && W == '1' then SEE LDRT;
5808                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5809                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5810                t = Bits32 (opcode, 15, 12);
5811                n = Bits32 (opcode, 19, 16);
5812                imm32 = Bits32 (opcode, 11, 0);
5813
5814                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5815                index = BitIsSet (opcode, 24);
5816                add = BitIsSet (opcode, 23);
5817                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5818
5819                // if wback && n == t then UNPREDICTABLE;
5820                if (wback && (n == t))
5821                    return false;
5822
5823                break;
5824
5825            default:
5826                return false;
5827        }
5828
5829        addr_t address;
5830        addr_t offset_addr;
5831        addr_t base_address = ReadCoreReg (n, &success);
5832        if (!success)
5833            return false;
5834
5835        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5836        if (add)
5837            offset_addr = base_address + imm32;
5838        else
5839            offset_addr = base_address - imm32;
5840
5841        // address = if index then offset_addr else R[n];
5842        if (index)
5843            address = offset_addr;
5844        else
5845            address = base_address;
5846
5847        // data = MemU[address,4];
5848
5849        RegisterInfo base_reg;
5850        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5851
5852        EmulateInstruction::Context context;
5853        context.type = eContextRegisterLoad;
5854        context.SetRegisterPlusOffset (base_reg, address - base_address);
5855
5856        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5857        if (!success)
5858            return false;
5859
5860        // if wback then R[n] = offset_addr;
5861        if (wback)
5862        {
5863            context.type = eContextAdjustBaseRegister;
5864            context.SetAddress (offset_addr);
5865            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5866                return false;
5867        }
5868
5869        // if t == 15 then
5870        if (t == 15)
5871        {
5872            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5873            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5874            {
5875                // LoadWritePC (data);
5876                context.type = eContextRegisterLoad;
5877                context.SetRegisterPlusOffset (base_reg, address - base_address);
5878                LoadWritePC (context, data);
5879            }
5880            else
5881                  return false;
5882        }
5883        // elsif UnalignedSupport() || address<1:0> = '00' then
5884        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5885        {
5886            // R[t] = data;
5887            context.type = eContextRegisterLoad;
5888            context.SetRegisterPlusOffset (base_reg, address - base_address);
5889            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5890                return false;
5891        }
5892        // else // Can only apply before ARMv7
5893        else
5894        {
5895            // R[t] = ROR(data, 8*UInt(address<1:0>));
5896            data = ROR (data, Bits32 (address, 1, 0), &success);
5897            if (!success)
5898                return false;
5899            context.type = eContextRegisterLoad;
5900            context.SetImmediate (data);
5901            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5902                return false;
5903        }
5904
5905    }
5906    return true;
5907}
5908
5909// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5910// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5911bool
5912EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5913{
5914#if 0
5915    if ConditionPassed() then
5916        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5917        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5918        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5919        address = if index then offset_addr else R[n];
5920        data = MemU[address,4];
5921        if wback then R[n] = offset_addr;
5922        if t == 15 then
5923            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5924        elsif UnalignedSupport() || address<1:0> = '00' then
5925            R[t] = data;
5926        else // Can only apply before ARMv7
5927            if CurrentInstrSet() == InstrSet_ARM then
5928                R[t] = ROR(data, 8*UInt(address<1:0>));
5929            else
5930                R[t] = bits(32) UNKNOWN;
5931#endif
5932
5933    bool success = false;
5934
5935    if (ConditionPassed(opcode))
5936    {
5937        const uint32_t addr_byte_size = GetAddressByteSize();
5938
5939        uint32_t t;
5940        uint32_t n;
5941        uint32_t m;
5942        bool index;
5943        bool add;
5944        bool wback;
5945        ARM_ShifterType shift_t;
5946        uint32_t shift_n;
5947
5948        switch (encoding)
5949        {
5950            case eEncodingT1:
5951                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5952                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5953                t = Bits32 (opcode, 2, 0);
5954                n = Bits32 (opcode, 5, 3);
5955                m = Bits32 (opcode, 8, 6);
5956
5957                // index = TRUE; add = TRUE; wback = FALSE;
5958                index = true;
5959                add = true;
5960                wback = false;
5961
5962                // (shift_t, shift_n) = (SRType_LSL, 0);
5963                shift_t = SRType_LSL;
5964                shift_n = 0;
5965
5966                break;
5967
5968            case eEncodingT2:
5969                // if Rn == '1111' then SEE LDR (literal);
5970                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5971                t = Bits32 (opcode, 15, 12);
5972                n = Bits32 (opcode, 19, 16);
5973                m = Bits32 (opcode, 3, 0);
5974
5975                // index = TRUE; add = TRUE; wback = FALSE;
5976                index = true;
5977                add = true;
5978                wback = false;
5979
5980                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5981                shift_t = SRType_LSL;
5982                shift_n = Bits32 (opcode, 5, 4);
5983
5984                // if BadReg(m) then UNPREDICTABLE;
5985                if (BadReg (m))
5986                    return false;
5987
5988                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5989                if ((t == 15) && InITBlock() && !LastInITBlock())
5990                    return false;
5991
5992                break;
5993
5994            case eEncodingA1:
5995            {
5996                // if P == '0' && W == '1' then SEE LDRT;
5997                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5998                t = Bits32 (opcode, 15, 12);
5999                n = Bits32 (opcode, 19, 16);
6000                m = Bits32 (opcode, 3, 0);
6001
6002                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6003                index = BitIsSet (opcode, 24);
6004                add = BitIsSet (opcode, 23);
6005                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6006
6007                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6008                uint32_t type = Bits32 (opcode, 6, 5);
6009                uint32_t imm5 = Bits32 (opcode, 11, 7);
6010                shift_n = DecodeImmShift (type, imm5, shift_t);
6011
6012                // if m == 15 then UNPREDICTABLE;
6013                if (m == 15)
6014                    return false;
6015
6016                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6017                if (wback && ((n == 15) || (n == t)))
6018                    return false;
6019            }
6020                break;
6021
6022
6023            default:
6024                return false;
6025        }
6026
6027        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6028        if (!success)
6029            return false;
6030
6031        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6032        if (!success)
6033            return false;
6034
6035        addr_t offset_addr;
6036        addr_t address;
6037
6038        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6039        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6040        if (!success)
6041            return false;
6042
6043        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6044        if (add)
6045            offset_addr = Rn + offset;
6046        else
6047            offset_addr = Rn - offset;
6048
6049        // address = if index then offset_addr else R[n];
6050            if (index)
6051                address = offset_addr;
6052            else
6053                address = Rn;
6054
6055        // data = MemU[address,4];
6056        RegisterInfo base_reg;
6057        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6058
6059        EmulateInstruction::Context context;
6060        context.type = eContextRegisterLoad;
6061        context.SetRegisterPlusOffset (base_reg, address - Rn);
6062
6063        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6064        if (!success)
6065            return false;
6066
6067        // if wback then R[n] = offset_addr;
6068        if (wback)
6069        {
6070            context.type = eContextAdjustBaseRegister;
6071            context.SetAddress (offset_addr);
6072            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6073                return false;
6074        }
6075
6076        // if t == 15 then
6077        if (t == 15)
6078        {
6079            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6080            if (BitIsClear (address, 1) && BitIsClear (address, 0))
6081            {
6082                context.type = eContextRegisterLoad;
6083                context.SetRegisterPlusOffset (base_reg, address - Rn);
6084                LoadWritePC (context, data);
6085            }
6086            else
6087                return false;
6088        }
6089        // elsif UnalignedSupport() || address<1:0> = '00' then
6090        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6091        {
6092            // R[t] = data;
6093            context.type = eContextRegisterLoad;
6094            context.SetRegisterPlusOffset (base_reg, address - Rn);
6095            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6096                return false;
6097        }
6098        else // Can only apply before ARMv7
6099        {
6100            // if CurrentInstrSet() == InstrSet_ARM then
6101            if (CurrentInstrSet () == eModeARM)
6102            {
6103                // R[t] = ROR(data, 8*UInt(address<1:0>));
6104                data = ROR (data, Bits32 (address, 1, 0), &success);
6105                if (!success)
6106                    return false;
6107                context.type = eContextRegisterLoad;
6108                context.SetImmediate (data);
6109                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6110                    return false;
6111            }
6112            else
6113            {
6114                // R[t] = bits(32) UNKNOWN;
6115                WriteBits32Unknown (t);
6116            }
6117        }
6118    }
6119    return true;
6120}
6121
6122// LDRB (immediate, Thumb)
6123bool
6124EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6125{
6126#if 0
6127    if ConditionPassed() then
6128        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6129        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6130        address = if index then offset_addr else R[n];
6131        R[t] = ZeroExtend(MemU[address,1], 32);
6132        if wback then R[n] = offset_addr;
6133#endif
6134
6135    bool success = false;
6136
6137    if (ConditionPassed(opcode))
6138    {
6139        uint32_t t;
6140        uint32_t n;
6141        uint32_t imm32;
6142        bool index;
6143        bool add;
6144        bool wback;
6145
6146        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6147        switch (encoding)
6148        {
6149            case eEncodingT1:
6150                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6151                t = Bits32 (opcode, 2, 0);
6152                n = Bits32 (opcode, 5, 3);
6153                imm32 = Bits32 (opcode, 10, 6);
6154
6155                // index = TRUE; add = TRUE; wback = FALSE;
6156                index = true;
6157                add = true;
6158                wback= false;
6159
6160                break;
6161
6162            case eEncodingT2:
6163                // if Rt == '1111' then SEE PLD;
6164                // if Rn == '1111' then SEE LDRB (literal);
6165                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6166                t = Bits32 (opcode, 15, 12);
6167                n = Bits32 (opcode, 19, 16);
6168                imm32 = Bits32 (opcode, 11, 0);
6169
6170                // index = TRUE; add = TRUE; wback = FALSE;
6171                index = true;
6172                add = true;
6173                wback = false;
6174
6175                // if t == 13 then UNPREDICTABLE;
6176                if (t == 13)
6177                    return false;
6178
6179                break;
6180
6181            case eEncodingT3:
6182                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6183                // if Rn == '1111' then SEE LDRB (literal);
6184                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6185                // if P == '0' && W == '0' then UNDEFINED;
6186                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6187                    return false;
6188
6189                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6190                t = Bits32 (opcode, 15, 12);
6191                n = Bits32 (opcode, 19, 16);
6192                imm32 = Bits32 (opcode, 7, 0);
6193
6194                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6195                index = BitIsSet (opcode, 10);
6196                add = BitIsSet (opcode, 9);
6197                wback = BitIsSet (opcode, 8);
6198
6199                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6200                if (BadReg (t) || (wback && (n == t)))
6201                    return false;
6202
6203                break;
6204
6205            default:
6206                return false;
6207        }
6208
6209        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6210        if (!success)
6211            return false;
6212
6213        addr_t address;
6214        addr_t offset_addr;
6215
6216        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6217        if (add)
6218            offset_addr = Rn + imm32;
6219        else
6220            offset_addr = Rn - imm32;
6221
6222        // address = if index then offset_addr else R[n];
6223        if (index)
6224            address = offset_addr;
6225        else
6226            address = Rn;
6227
6228        // R[t] = ZeroExtend(MemU[address,1], 32);
6229        RegisterInfo base_reg;
6230        RegisterInfo data_reg;
6231        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6232        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6233
6234        EmulateInstruction::Context context;
6235        context.type = eContextRegisterLoad;
6236        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6237
6238        uint64_t data = MemURead (context, address, 1, 0, &success);
6239        if (!success)
6240            return false;
6241
6242        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6243            return false;
6244
6245        // if wback then R[n] = offset_addr;
6246        if (wback)
6247        {
6248            context.type = eContextAdjustBaseRegister;
6249            context.SetAddress (offset_addr);
6250            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6251                return false;
6252        }
6253    }
6254    return true;
6255}
6256
6257// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6258// zero-extends it to form a 32-bit word and writes it to a register.
6259bool
6260EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6261{
6262#if 0
6263    if ConditionPassed() then
6264        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6265        base = Align(PC,4);
6266        address = if add then (base + imm32) else (base - imm32);
6267        R[t] = ZeroExtend(MemU[address,1], 32);
6268#endif
6269
6270    bool success = false;
6271
6272    if (ConditionPassed(opcode))
6273    {
6274        uint32_t t;
6275        uint32_t imm32;
6276        bool add;
6277        switch (encoding)
6278        {
6279            case eEncodingT1:
6280                // if Rt == '1111' then SEE PLD;
6281                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6282                t = Bits32 (opcode, 15, 12);
6283                imm32 = Bits32 (opcode, 11, 0);
6284                add = BitIsSet (opcode, 23);
6285
6286                // if t == 13 then UNPREDICTABLE;
6287                if (t == 13)
6288                    return false;
6289
6290                break;
6291
6292            case eEncodingA1:
6293                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6294                t = Bits32 (opcode, 15, 12);
6295                imm32 = Bits32 (opcode, 11, 0);
6296                add = BitIsSet (opcode, 23);
6297
6298                // if t == 15 then UNPREDICTABLE;
6299                if (t == 15)
6300                    return false;
6301                break;
6302
6303            default:
6304                return false;
6305        }
6306
6307        // base = Align(PC,4);
6308        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6309        if (!success)
6310            return false;
6311
6312        uint32_t base = AlignPC (pc_val);
6313
6314        addr_t address;
6315        // address = if add then (base + imm32) else (base - imm32);
6316        if (add)
6317            address = base + imm32;
6318        else
6319            address = base - imm32;
6320
6321        // R[t] = ZeroExtend(MemU[address,1], 32);
6322        EmulateInstruction::Context context;
6323        context.type = eContextRelativeBranchImmediate;
6324        context.SetImmediate (address - base);
6325
6326        uint64_t data = MemURead (context, address, 1, 0, &success);
6327        if (!success)
6328            return false;
6329
6330        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6331            return false;
6332    }
6333    return true;
6334}
6335
6336// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6337// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6338// optionally be shifted.
6339bool
6340EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6341{
6342#if 0
6343    if ConditionPassed() then
6344        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6345        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6346        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6347        address = if index then offset_addr else R[n];
6348        R[t] = ZeroExtend(MemU[address,1],32);
6349        if wback then R[n] = offset_addr;
6350#endif
6351
6352    bool success = false;
6353
6354    if (ConditionPassed(opcode))
6355    {
6356        uint32_t t;
6357        uint32_t n;
6358        uint32_t m;
6359        bool index;
6360        bool add;
6361        bool wback;
6362        ARM_ShifterType shift_t;
6363        uint32_t shift_n;
6364
6365        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6366        switch (encoding)
6367        {
6368            case eEncodingT1:
6369                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6370                t = Bits32 (opcode, 2, 0);
6371                n = Bits32 (opcode, 5, 3);
6372                m = Bits32 (opcode, 8, 6);
6373
6374                // index = TRUE; add = TRUE; wback = FALSE;
6375                index = true;
6376                add = true;
6377                wback = false;
6378
6379                // (shift_t, shift_n) = (SRType_LSL, 0);
6380                shift_t = SRType_LSL;
6381                shift_n = 0;
6382                break;
6383
6384            case eEncodingT2:
6385                // if Rt == '1111' then SEE PLD;
6386                // if Rn == '1111' then SEE LDRB (literal);
6387                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6388                t = Bits32 (opcode, 15, 12);
6389                n = Bits32 (opcode, 19, 16);
6390                m = Bits32 (opcode, 3, 0);
6391
6392                // index = TRUE; add = TRUE; wback = FALSE;
6393                index = true;
6394                add = true;
6395                wback = false;
6396
6397                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6398                shift_t = SRType_LSL;
6399                shift_n = Bits32 (opcode, 5, 4);
6400
6401                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6402                if ((t == 13) || BadReg (m))
6403                    return false;
6404                break;
6405
6406            case eEncodingA1:
6407            {
6408                // if P == '0' && W == '1' then SEE LDRBT;
6409                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6410                t = Bits32 (opcode, 15, 12);
6411                n = Bits32 (opcode, 19, 16);
6412                m = Bits32 (opcode, 3, 0);
6413
6414                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6415                index = BitIsSet (opcode, 24);
6416                add = BitIsSet (opcode, 23);
6417                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6418
6419                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6420                uint32_t type = Bits32 (opcode, 6, 5);
6421                uint32_t imm5 = Bits32 (opcode, 11, 7);
6422                shift_n = DecodeImmShift (type, imm5, shift_t);
6423
6424                // if t == 15 || m == 15 then UNPREDICTABLE;
6425                if ((t == 15) || (m == 15))
6426                    return false;
6427
6428                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6429                if (wback && ((n == 15) || (n == t)))
6430                    return false;
6431            }
6432                break;
6433
6434            default:
6435                return false;
6436        }
6437
6438        addr_t offset_addr;
6439        addr_t address;
6440
6441        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6442        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6443        if (!success)
6444            return false;
6445
6446        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6447        if (!success)
6448            return false;
6449
6450        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6451        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6452        if (!success)
6453            return false;
6454
6455        if (add)
6456            offset_addr = Rn + offset;
6457        else
6458            offset_addr = Rn - offset;
6459
6460        // address = if index then offset_addr else R[n];
6461        if (index)
6462            address = offset_addr;
6463        else
6464            address = Rn;
6465
6466        // R[t] = ZeroExtend(MemU[address,1],32);
6467        RegisterInfo base_reg;
6468        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6469
6470        EmulateInstruction::Context context;
6471        context.type = eContextRegisterLoad;
6472        context.SetRegisterPlusOffset (base_reg, address - Rn);
6473
6474        uint64_t data = MemURead (context, address, 1, 0, &success);
6475        if (!success)
6476            return false;
6477
6478        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6479            return false;
6480
6481        // if wback then R[n] = offset_addr;
6482        if (wback)
6483        {
6484            context.type = eContextAdjustBaseRegister;
6485            context.SetAddress (offset_addr);
6486            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6487                return false;
6488        }
6489    }
6490    return true;
6491}
6492
6493// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6494// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6495// post-indexed, or pre-indexed addressing.
6496bool
6497EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6498{
6499#if 0
6500    if ConditionPassed() then
6501        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6502        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6503        address = if index then offset_addr else R[n];
6504        data = MemU[address,2];
6505        if wback then R[n] = offset_addr;
6506        if UnalignedSupport() || address<0> = '0' then
6507            R[t] = ZeroExtend(data, 32);
6508        else // Can only apply before ARMv7
6509            R[t] = bits(32) UNKNOWN;
6510#endif
6511
6512
6513    bool success = false;
6514
6515    if (ConditionPassed(opcode))
6516    {
6517        uint32_t t;
6518        uint32_t n;
6519        uint32_t imm32;
6520        bool index;
6521        bool add;
6522        bool wback;
6523
6524        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6525        switch (encoding)
6526        {
6527            case eEncodingT1:
6528                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6529                t = Bits32 (opcode, 2, 0);
6530                n = Bits32 (opcode, 5, 3);
6531                imm32 = Bits32 (opcode, 10, 6) << 1;
6532
6533                // index = TRUE; add = TRUE; wback = FALSE;
6534                index = true;
6535                add = true;
6536                wback = false;
6537
6538                break;
6539
6540            case eEncodingT2:
6541                // if Rt == '1111' then SEE "Unallocated memory hints";
6542                // if Rn == '1111' then SEE LDRH (literal);
6543                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6544                t = Bits32 (opcode, 15, 12);
6545                n = Bits32 (opcode, 19, 16);
6546                imm32 = Bits32 (opcode, 11, 0);
6547
6548                // index = TRUE; add = TRUE; wback = FALSE;
6549                index = true;
6550                add = true;
6551                wback = false;
6552
6553                // if t == 13 then UNPREDICTABLE;
6554                if (t == 13)
6555                    return false;
6556                break;
6557
6558            case eEncodingT3:
6559                // if Rn == '1111' then SEE LDRH (literal);
6560                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6561                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6562                // if P == '0' && W == '0' then UNDEFINED;
6563                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6564                    return false;
6565
6566                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6567                t = Bits32 (opcode, 15, 12);
6568                n = Bits32 (opcode, 19, 16);
6569                imm32 = Bits32 (opcode, 7, 0);
6570
6571                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6572                index = BitIsSet (opcode, 10);
6573                add = BitIsSet (opcode, 9);
6574                wback = BitIsSet (opcode, 8);
6575
6576                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6577                if (BadReg (t) || (wback && (n == t)))
6578                    return false;
6579                break;
6580
6581            default:
6582                return false;
6583        }
6584
6585        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6586        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6587        if (!success)
6588            return false;
6589
6590        addr_t offset_addr;
6591        addr_t address;
6592
6593        if (add)
6594            offset_addr = Rn + imm32;
6595        else
6596            offset_addr = Rn - imm32;
6597
6598        // address = if index then offset_addr else R[n];
6599        if (index)
6600            address = offset_addr;
6601        else
6602            address = Rn;
6603
6604        // data = MemU[address,2];
6605        RegisterInfo base_reg;
6606        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6607
6608        EmulateInstruction::Context context;
6609        context.type = eContextRegisterLoad;
6610        context.SetRegisterPlusOffset (base_reg, address - Rn);
6611
6612        uint64_t data = MemURead (context, address, 2, 0, &success);
6613        if (!success)
6614            return false;
6615
6616        // if wback then R[n] = offset_addr;
6617        if (wback)
6618        {
6619            context.type = eContextAdjustBaseRegister;
6620            context.SetAddress (offset_addr);
6621            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6622                return false;
6623        }
6624
6625        // if UnalignedSupport() || address<0> = '0' then
6626        if (UnalignedSupport () || BitIsClear (address, 0))
6627        {
6628            // R[t] = ZeroExtend(data, 32);
6629            context.type = eContextRegisterLoad;
6630            context.SetRegisterPlusOffset (base_reg, address - Rn);
6631            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6632                return false;
6633        }
6634        else // Can only apply before ARMv7
6635        {
6636            // R[t] = bits(32) UNKNOWN;
6637            WriteBits32Unknown (t);
6638        }
6639    }
6640    return true;
6641}
6642
6643// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6644// zero-extends it to form a 32-bit word, and writes it to a register.
6645bool
6646EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6647{
6648#if 0
6649    if ConditionPassed() then
6650        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6651        base = Align(PC,4);
6652        address = if add then (base + imm32) else (base - imm32);
6653        data = MemU[address,2];
6654        if UnalignedSupport() || address<0> = '0' then
6655            R[t] = ZeroExtend(data, 32);
6656        else // Can only apply before ARMv7
6657            R[t] = bits(32) UNKNOWN;
6658#endif
6659
6660    bool success = false;
6661
6662    if (ConditionPassed(opcode))
6663    {
6664        uint32_t t;
6665        uint32_t imm32;
6666        bool add;
6667
6668        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6669        switch (encoding)
6670        {
6671            case eEncodingT1:
6672                // if Rt == '1111' then SEE "Unallocated memory hints";
6673                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6674                t = Bits32 (opcode, 15, 12);
6675                imm32 = Bits32 (opcode, 11, 0);
6676                add = BitIsSet (opcode, 23);
6677
6678                // if t == 13 then UNPREDICTABLE;
6679                if (t == 13)
6680                    return false;
6681
6682                break;
6683
6684            case eEncodingA1:
6685            {
6686                uint32_t imm4H = Bits32 (opcode, 11, 8);
6687                uint32_t imm4L = Bits32 (opcode, 3, 0);
6688
6689                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6690                t = Bits32 (opcode, 15, 12);
6691                imm32 = (imm4H << 4) | imm4L;
6692                add = BitIsSet (opcode, 23);
6693
6694                // if t == 15 then UNPREDICTABLE;
6695                if (t == 15)
6696                    return false;
6697                break;
6698            }
6699
6700            default:
6701                return false;
6702        }
6703
6704        // base = Align(PC,4);
6705        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6706        if (!success)
6707            return false;
6708
6709        addr_t base = AlignPC (pc_value);
6710        addr_t address;
6711
6712        // address = if add then (base + imm32) else (base - imm32);
6713        if (add)
6714            address = base + imm32;
6715        else
6716            address = base - imm32;
6717
6718        // data = MemU[address,2];
6719        RegisterInfo base_reg;
6720        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6721
6722        EmulateInstruction::Context context;
6723        context.type = eContextRegisterLoad;
6724        context.SetRegisterPlusOffset (base_reg, address - base);
6725
6726        uint64_t data = MemURead (context, address, 2, 0, &success);
6727        if (!success)
6728            return false;
6729
6730
6731        // if UnalignedSupport() || address<0> = '0' then
6732        if (UnalignedSupport () || BitIsClear (address, 0))
6733        {
6734            // R[t] = ZeroExtend(data, 32);
6735            context.type = eContextRegisterLoad;
6736            context.SetRegisterPlusOffset (base_reg, address - base);
6737            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6738                return false;
6739
6740        }
6741        else // Can only apply before ARMv7
6742        {
6743            // R[t] = bits(32) UNKNOWN;
6744            WriteBits32Unknown (t);
6745        }
6746    }
6747    return true;
6748}
6749
6750// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6751// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6752// be shifted left by 0, 1, 2, or 3 bits.
6753bool
6754EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6755{
6756#if 0
6757    if ConditionPassed() then
6758        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6759        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6760        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6761        address = if index then offset_addr else R[n];
6762        data = MemU[address,2];
6763        if wback then R[n] = offset_addr;
6764        if UnalignedSupport() || address<0> = '0' then
6765            R[t] = ZeroExtend(data, 32);
6766        else // Can only apply before ARMv7
6767            R[t] = bits(32) UNKNOWN;
6768#endif
6769
6770    bool success = false;
6771
6772    if (ConditionPassed(opcode))
6773    {
6774        uint32_t t;
6775        uint32_t n;
6776        uint32_t m;
6777        bool index;
6778        bool add;
6779        bool wback;
6780        ARM_ShifterType shift_t;
6781        uint32_t shift_n;
6782
6783        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6784        switch (encoding)
6785        {
6786            case eEncodingT1:
6787                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6788                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6789                t = Bits32 (opcode, 2, 0);
6790                n = Bits32 (opcode, 5, 3);
6791                m = Bits32 (opcode, 8, 6);
6792
6793                // index = TRUE; add = TRUE; wback = FALSE;
6794                index = true;
6795                add = true;
6796                wback = false;
6797
6798                // (shift_t, shift_n) = (SRType_LSL, 0);
6799                shift_t = SRType_LSL;
6800                shift_n = 0;
6801
6802                break;
6803
6804            case eEncodingT2:
6805                // if Rn == '1111' then SEE LDRH (literal);
6806                // if Rt == '1111' then SEE "Unallocated memory hints";
6807                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6808                t = Bits32 (opcode, 15, 12);
6809                n = Bits32 (opcode, 19, 16);
6810                m = Bits32 (opcode, 3, 0);
6811
6812                // index = TRUE; add = TRUE; wback = FALSE;
6813                index = true;
6814                add = true;
6815                wback = false;
6816
6817                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6818                shift_t = SRType_LSL;
6819                shift_n = Bits32 (opcode, 5, 4);
6820
6821                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6822                if ((t == 13) || BadReg (m))
6823                    return false;
6824                break;
6825
6826            case eEncodingA1:
6827                // if P == '0' && W == '1' then SEE LDRHT;
6828                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6829                t = Bits32 (opcode, 15, 12);
6830                n = Bits32 (opcode, 19, 16);
6831                m = Bits32 (opcode, 3, 0);
6832
6833                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6834                index = BitIsSet (opcode, 24);
6835                add = BitIsSet (opcode, 23);
6836                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6837
6838                // (shift_t, shift_n) = (SRType_LSL, 0);
6839                shift_t = SRType_LSL;
6840                shift_n = 0;
6841
6842                // if t == 15 || m == 15 then UNPREDICTABLE;
6843                if ((t == 15) || (m == 15))
6844                    return false;
6845
6846                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6847                if (wback && ((n == 15) || (n == t)))
6848                    return false;
6849
6850                break;
6851
6852            default:
6853                return false;
6854        }
6855
6856        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6857
6858        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6859        if (!success)
6860            return false;
6861
6862        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6863        if (!success)
6864            return false;
6865
6866        addr_t offset_addr;
6867        addr_t address;
6868
6869        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6870        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6871        if (!success)
6872            return false;
6873
6874        if (add)
6875            offset_addr = Rn + offset;
6876        else
6877            offset_addr = Rn - offset;
6878
6879        // address = if index then offset_addr else R[n];
6880        if (index)
6881            address = offset_addr;
6882        else
6883            address = Rn;
6884
6885        // data = MemU[address,2];
6886        RegisterInfo base_reg;
6887        RegisterInfo offset_reg;
6888        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6889        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6890
6891        EmulateInstruction::Context context;
6892        context.type = eContextRegisterLoad;
6893        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6894        uint64_t data = MemURead (context, address, 2, 0, &success);
6895        if (!success)
6896            return false;
6897
6898        // if wback then R[n] = offset_addr;
6899        if (wback)
6900        {
6901            context.type = eContextAdjustBaseRegister;
6902            context.SetAddress (offset_addr);
6903            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6904                return false;
6905        }
6906
6907        // if UnalignedSupport() || address<0> = '0' then
6908        if (UnalignedSupport() || BitIsClear (address, 0))
6909        {
6910            // R[t] = ZeroExtend(data, 32);
6911            context.type = eContextRegisterLoad;
6912            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6913            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6914                return false;
6915        }
6916        else // Can only apply before ARMv7
6917        {
6918            // R[t] = bits(32) UNKNOWN;
6919            WriteBits32Unknown (t);
6920        }
6921    }
6922    return true;
6923}
6924
6925// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6926// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6927// or pre-indexed addressing.
6928bool
6929EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6930{
6931#if 0
6932    if ConditionPassed() then
6933        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6934        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6935        address = if index then offset_addr else R[n];
6936        R[t] = SignExtend(MemU[address,1], 32);
6937        if wback then R[n] = offset_addr;
6938#endif
6939
6940    bool success = false;
6941
6942    if (ConditionPassed(opcode))
6943    {
6944        uint32_t t;
6945        uint32_t n;
6946        uint32_t imm32;
6947        bool index;
6948        bool add;
6949        bool wback;
6950
6951        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6952        switch (encoding)
6953        {
6954            case eEncodingT1:
6955                // if Rt == '1111' then SEE PLI;
6956                // if Rn == '1111' then SEE LDRSB (literal);
6957                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6958                t = Bits32 (opcode, 15, 12);
6959                n = Bits32 (opcode, 19, 16);
6960                imm32 = Bits32 (opcode, 11, 0);
6961
6962                // index = TRUE; add = TRUE; wback = FALSE;
6963                index = true;
6964                add = true;
6965                wback = false;
6966
6967                // if t == 13 then UNPREDICTABLE;
6968                if (t == 13)
6969                    return false;
6970
6971                break;
6972
6973            case eEncodingT2:
6974                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6975                // if Rn == '1111' then SEE LDRSB (literal);
6976                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6977                // if P == '0' && W == '0' then UNDEFINED;
6978                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6979                    return false;
6980
6981                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6982                t = Bits32 (opcode, 15, 12);
6983                n = Bits32 (opcode, 19, 16);
6984                imm32 = Bits32 (opcode, 7, 0);
6985
6986                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6987                index = BitIsSet (opcode, 10);
6988                add = BitIsSet (opcode, 9);
6989                wback = BitIsSet (opcode, 8);
6990
6991                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6992                  if (((t == 13) || ((t == 15)
6993                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6994                      || (wback && (n == t)))
6995                    return false;
6996
6997                break;
6998
6999            case eEncodingA1:
7000            {
7001                // if Rn == '1111' then SEE LDRSB (literal);
7002                // if P == '0' && W == '1' then SEE LDRSBT;
7003                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7004                t = Bits32 (opcode, 15, 12);
7005                n = Bits32 (opcode, 19, 16);
7006
7007                uint32_t imm4H = Bits32 (opcode, 11, 8);
7008                uint32_t imm4L = Bits32 (opcode, 3, 0);
7009                imm32 = (imm4H << 4) | imm4L;
7010
7011                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7012                index = BitIsSet (opcode, 24);
7013                add = BitIsSet (opcode, 23);
7014                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7015
7016                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7017                if ((t == 15) || (wback && (n == t)))
7018                    return false;
7019
7020                break;
7021            }
7022
7023            default:
7024                return false;
7025        }
7026
7027        uint64_t Rn = ReadCoreReg (n, &success);
7028        if (!success)
7029            return false;
7030
7031        addr_t offset_addr;
7032        addr_t address;
7033
7034        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7035        if (add)
7036            offset_addr = Rn + imm32;
7037        else
7038            offset_addr = Rn - imm32;
7039
7040        // address = if index then offset_addr else R[n];
7041        if (index)
7042            address = offset_addr;
7043        else
7044            address = Rn;
7045
7046        // R[t] = SignExtend(MemU[address,1], 32);
7047        RegisterInfo base_reg;
7048        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7049
7050        EmulateInstruction::Context context;
7051        context.type = eContextRegisterLoad;
7052        context.SetRegisterPlusOffset (base_reg, address - Rn);
7053
7054        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7055        if (!success)
7056            return false;
7057
7058        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7059        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7060            return false;
7061
7062        // if wback then R[n] = offset_addr;
7063        if (wback)
7064        {
7065            context.type = eContextAdjustBaseRegister;
7066            context.SetAddress (offset_addr);
7067            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7068                return false;
7069        }
7070    }
7071
7072    return true;
7073}
7074
7075// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7076// sign-extends it to form a 32-bit word, and writes tit to a register.
7077bool
7078EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7079{
7080#if 0
7081    if ConditionPassed() then
7082        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7083        base = Align(PC,4);
7084        address = if add then (base + imm32) else (base - imm32);
7085        R[t] = SignExtend(MemU[address,1], 32);
7086#endif
7087
7088    bool success = false;
7089
7090    if (ConditionPassed(opcode))
7091    {
7092        uint32_t t;
7093        uint32_t imm32;
7094        bool add;
7095
7096        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7097        switch (encoding)
7098        {
7099            case eEncodingT1:
7100                // if Rt == '1111' then SEE PLI;
7101                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7102                t = Bits32 (opcode, 15, 12);
7103                imm32 = Bits32 (opcode, 11, 0);
7104                add = BitIsSet (opcode, 23);
7105
7106                // if t == 13 then UNPREDICTABLE;
7107                if (t == 13)
7108                    return false;
7109
7110                break;
7111
7112            case eEncodingA1:
7113            {
7114                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7115                t = Bits32 (opcode, 15, 12);
7116                uint32_t imm4H = Bits32 (opcode, 11, 8);
7117                uint32_t imm4L = Bits32 (opcode, 3, 0);
7118                imm32 = (imm4H << 4) | imm4L;
7119                add = BitIsSet (opcode, 23);
7120
7121                // if t == 15 then UNPREDICTABLE;
7122                if (t == 15)
7123                    return false;
7124
7125                break;
7126            }
7127
7128            default:
7129                return false;
7130        }
7131
7132        // base = Align(PC,4);
7133        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7134        if (!success)
7135            return false;
7136        uint64_t base = AlignPC (pc_value);
7137
7138        // address = if add then (base + imm32) else (base - imm32);
7139        addr_t address;
7140        if (add)
7141            address = base + imm32;
7142        else
7143            address = base - imm32;
7144
7145        // R[t] = SignExtend(MemU[address,1], 32);
7146        RegisterInfo base_reg;
7147        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7148
7149        EmulateInstruction::Context context;
7150        context.type = eContextRegisterLoad;
7151        context.SetRegisterPlusOffset (base_reg, address - base);
7152
7153        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7154        if (!success)
7155            return false;
7156
7157        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7158        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7159            return false;
7160    }
7161    return true;
7162}
7163
7164// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7165// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7166// shifted left by 0, 1, 2, or 3 bits.
7167bool
7168EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7169{
7170#if 0
7171    if ConditionPassed() then
7172        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7173        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7174        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7175        address = if index then offset_addr else R[n];
7176        R[t] = SignExtend(MemU[address,1], 32);
7177        if wback then R[n] = offset_addr;
7178#endif
7179
7180    bool success = false;
7181
7182    if (ConditionPassed(opcode))
7183    {
7184        uint32_t t;
7185        uint32_t n;
7186        uint32_t m;
7187        bool index;
7188        bool add;
7189        bool wback;
7190        ARM_ShifterType shift_t;
7191        uint32_t shift_n;
7192
7193        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7194        switch (encoding)
7195        {
7196            case eEncodingT1:
7197                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7198                t = Bits32 (opcode, 2, 0);
7199                n = Bits32 (opcode, 5, 3);
7200                m = Bits32 (opcode, 8, 6);
7201
7202                // index = TRUE; add = TRUE; wback = FALSE;
7203                index = true;
7204                add = true;
7205                wback = false;
7206
7207                // (shift_t, shift_n) = (SRType_LSL, 0);
7208                shift_t = SRType_LSL;
7209                shift_n = 0;
7210
7211                break;
7212
7213            case eEncodingT2:
7214                // if Rt == '1111' then SEE PLI;
7215                // if Rn == '1111' then SEE LDRSB (literal);
7216                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7217                t = Bits32 (opcode, 15, 12);
7218                n = Bits32 (opcode, 19, 16);
7219                m = Bits32 (opcode, 3, 0);
7220
7221                // index = TRUE; add = TRUE; wback = FALSE;
7222                index = true;
7223                add = true;
7224                wback = false;
7225
7226                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7227                shift_t = SRType_LSL;
7228                shift_n = Bits32 (opcode, 5, 4);
7229
7230                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7231                if ((t == 13) || BadReg (m))
7232                    return false;
7233                break;
7234
7235            case eEncodingA1:
7236                // if P == '0' && W == '1' then SEE LDRSBT;
7237                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7238                t = Bits32 (opcode, 15, 12);
7239                n = Bits32 (opcode, 19, 16);
7240                m = Bits32 (opcode, 3, 0);
7241
7242                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7243                index = BitIsSet (opcode, 24);
7244                add = BitIsSet (opcode, 23);
7245                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7246
7247                // (shift_t, shift_n) = (SRType_LSL, 0);
7248                shift_t = SRType_LSL;
7249                shift_n = 0;
7250
7251                // if t == 15 || m == 15 then UNPREDICTABLE;
7252                if ((t == 15) || (m == 15))
7253                    return false;
7254
7255                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7256                if (wback && ((n == 15) || (n == t)))
7257                    return false;
7258                break;
7259
7260            default:
7261                return false;
7262        }
7263
7264        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7265        if (!success)
7266            return false;
7267
7268        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7269        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7270        if (!success)
7271            return false;
7272
7273        addr_t offset_addr;
7274        addr_t address;
7275
7276        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7277        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7278        if (!success)
7279            return false;
7280
7281        if (add)
7282            offset_addr = Rn + offset;
7283        else
7284            offset_addr = Rn - offset;
7285
7286        // address = if index then offset_addr else R[n];
7287        if (index)
7288            address = offset_addr;
7289        else
7290            address = Rn;
7291
7292        // R[t] = SignExtend(MemU[address,1], 32);
7293        RegisterInfo base_reg;
7294        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7295        RegisterInfo offset_reg;
7296        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7297
7298        EmulateInstruction::Context context;
7299        context.type = eContextRegisterLoad;
7300        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7301
7302        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7303        if (!success)
7304            return false;
7305
7306        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7307        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7308            return false;
7309
7310        // if wback then R[n] = offset_addr;
7311        if (wback)
7312        {
7313            context.type = eContextAdjustBaseRegister;
7314            context.SetAddress (offset_addr);
7315            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7316                return false;
7317        }
7318    }
7319    return true;
7320}
7321
7322// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7323// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7324// pre-indexed addressing.
7325bool
7326EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7327{
7328#if 0
7329    if ConditionPassed() then
7330        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7331        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7332        address = if index then offset_addr else R[n];
7333        data = MemU[address,2];
7334        if wback then R[n] = offset_addr;
7335        if UnalignedSupport() || address<0> = '0' then
7336            R[t] = SignExtend(data, 32);
7337        else // Can only apply before ARMv7
7338            R[t] = bits(32) UNKNOWN;
7339#endif
7340
7341    bool success = false;
7342
7343    if (ConditionPassed(opcode))
7344    {
7345        uint32_t t;
7346        uint32_t n;
7347        uint32_t imm32;
7348        bool index;
7349        bool add;
7350        bool wback;
7351
7352        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7353        switch (encoding)
7354        {
7355            case eEncodingT1:
7356                // if Rn == '1111' then SEE LDRSH (literal);
7357                // if Rt == '1111' then SEE "Unallocated memory hints";
7358                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7359                t = Bits32 (opcode, 15, 12);
7360                n = Bits32 (opcode, 19, 16);
7361                imm32 = Bits32 (opcode, 11, 0);
7362
7363                // index = TRUE; add = TRUE; wback = FALSE;
7364                index = true;
7365                add = true;
7366                wback = false;
7367
7368                // if t == 13 then UNPREDICTABLE;
7369                if (t == 13)
7370                    return false;
7371
7372                break;
7373
7374            case eEncodingT2:
7375                // if Rn == '1111' then SEE LDRSH (literal);
7376                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7377                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7378                // if P == '0' && W == '0' then UNDEFINED;
7379                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7380                  return false;
7381
7382                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7383                t = Bits32 (opcode, 15, 12);
7384                n = Bits32 (opcode, 19, 16);
7385                imm32 = Bits32 (opcode, 7, 0);
7386
7387                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7388                index = BitIsSet (opcode, 10);
7389                add = BitIsSet (opcode, 9);
7390                wback = BitIsSet (opcode, 8);
7391
7392                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7393                if (BadReg (t) || (wback && (n == t)))
7394                    return false;
7395
7396                break;
7397
7398            case eEncodingA1:
7399            {
7400                // if Rn == '1111' then SEE LDRSH (literal);
7401                // if P == '0' && W == '1' then SEE LDRSHT;
7402                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7403                t = Bits32 (opcode, 15, 12);
7404                n = Bits32 (opcode, 19, 16);
7405                uint32_t imm4H = Bits32 (opcode, 11,8);
7406                uint32_t imm4L = Bits32 (opcode, 3, 0);
7407                imm32 = (imm4H << 4) | imm4L;
7408
7409                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7410                index = BitIsSet (opcode, 24);
7411                add = BitIsSet (opcode, 23);
7412                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7413
7414                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7415                if ((t == 15) || (wback && (n == t)))
7416                    return false;
7417
7418                break;
7419            }
7420
7421            default:
7422                return false;
7423        }
7424
7425        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7426        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7427        if (!success)
7428            return false;
7429
7430        addr_t offset_addr;
7431        if (add)
7432            offset_addr = Rn + imm32;
7433        else
7434            offset_addr = Rn - imm32;
7435
7436        // address = if index then offset_addr else R[n];
7437        addr_t address;
7438        if (index)
7439            address = offset_addr;
7440        else
7441            address = Rn;
7442
7443        // data = MemU[address,2];
7444        RegisterInfo base_reg;
7445        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7446
7447        EmulateInstruction::Context context;
7448        context.type = eContextRegisterLoad;
7449        context.SetRegisterPlusOffset (base_reg, address - Rn);
7450
7451        uint64_t data = MemURead (context, address, 2, 0, &success);
7452        if (!success)
7453            return false;
7454
7455        // if wback then R[n] = offset_addr;
7456        if (wback)
7457        {
7458            context.type = eContextAdjustBaseRegister;
7459            context.SetAddress (offset_addr);
7460            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7461                return false;
7462        }
7463
7464        // if UnalignedSupport() || address<0> = '0' then
7465        if (UnalignedSupport() || BitIsClear (address, 0))
7466        {
7467            // R[t] = SignExtend(data, 32);
7468            int64_t signed_data = llvm::SignExtend64<16>(data);
7469            context.type = eContextRegisterLoad;
7470            context.SetRegisterPlusOffset (base_reg, address - Rn);
7471            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7472                return false;
7473        }
7474        else // Can only apply before ARMv7
7475        {
7476            // R[t] = bits(32) UNKNOWN;
7477            WriteBits32Unknown (t);
7478        }
7479    }
7480    return true;
7481}
7482
7483// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7484// sign-extends it to from a 32-bit word, and writes it to a register.
7485bool
7486EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7487{
7488#if 0
7489    if ConditionPassed() then
7490        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7491        base = Align(PC,4);
7492        address = if add then (base + imm32) else (base - imm32);
7493        data = MemU[address,2];
7494        if UnalignedSupport() || address<0> = '0' then
7495            R[t] = SignExtend(data, 32);
7496        else // Can only apply before ARMv7
7497            R[t] = bits(32) UNKNOWN;
7498#endif
7499
7500    bool success = false;
7501
7502    if (ConditionPassed(opcode))
7503    {
7504        uint32_t t;
7505        uint32_t imm32;
7506        bool add;
7507
7508        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7509        switch (encoding)
7510        {
7511            case eEncodingT1:
7512                // if Rt == '1111' then SEE "Unallocated memory hints";
7513                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7514                t = Bits32  (opcode, 15, 12);
7515                imm32 = Bits32 (opcode, 11, 0);
7516                add = BitIsSet (opcode, 23);
7517
7518                // if t == 13 then UNPREDICTABLE;
7519                if (t == 13)
7520                    return false;
7521
7522                break;
7523
7524            case eEncodingA1:
7525            {
7526                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7527                t = Bits32 (opcode, 15, 12);
7528                uint32_t imm4H = Bits32 (opcode, 11, 8);
7529                uint32_t imm4L = Bits32 (opcode, 3, 0);
7530                imm32 = (imm4H << 4) | imm4L;
7531                add = BitIsSet (opcode, 23);
7532
7533                // if t == 15 then UNPREDICTABLE;
7534                if (t == 15)
7535                    return false;
7536
7537                break;
7538            }
7539            default:
7540                return false;
7541        }
7542
7543        // base = Align(PC,4);
7544        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7545        if (!success)
7546            return false;
7547
7548        uint64_t base = AlignPC (pc_value);
7549
7550        addr_t address;
7551        // address = if add then (base + imm32) else (base - imm32);
7552        if (add)
7553            address = base + imm32;
7554        else
7555            address = base - imm32;
7556
7557        // data = MemU[address,2];
7558        RegisterInfo base_reg;
7559        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7560
7561        EmulateInstruction::Context context;
7562        context.type = eContextRegisterLoad;
7563        context.SetRegisterPlusOffset (base_reg, imm32);
7564
7565        uint64_t data = MemURead (context, address, 2, 0, &success);
7566        if (!success)
7567            return false;
7568
7569        // if UnalignedSupport() || address<0> = '0' then
7570        if (UnalignedSupport() || BitIsClear (address, 0))
7571        {
7572            // R[t] = SignExtend(data, 32);
7573            int64_t signed_data = llvm::SignExtend64<16>(data);
7574            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7575                return false;
7576        }
7577        else // Can only apply before ARMv7
7578        {
7579            // R[t] = bits(32) UNKNOWN;
7580            WriteBits32Unknown (t);
7581        }
7582    }
7583    return true;
7584}
7585
7586// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7587// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7588// shifted left by 0, 1, 2, or 3 bits.
7589bool
7590EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7591{
7592#if 0
7593    if ConditionPassed() then
7594        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7595        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7596        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7597        address = if index then offset_addr else R[n];
7598        data = MemU[address,2];
7599        if wback then R[n] = offset_addr;
7600        if UnalignedSupport() || address<0> = '0' then
7601            R[t] = SignExtend(data, 32);
7602        else // Can only apply before ARMv7
7603            R[t] = bits(32) UNKNOWN;
7604#endif
7605
7606    bool success = false;
7607
7608    if (ConditionPassed(opcode))
7609    {
7610        uint32_t t;
7611        uint32_t n;
7612        uint32_t m;
7613        bool index;
7614        bool add;
7615        bool wback;
7616        ARM_ShifterType shift_t;
7617        uint32_t shift_n;
7618
7619        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7620        switch (encoding)
7621        {
7622            case eEncodingT1:
7623                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7624                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7625                t = Bits32 (opcode, 2, 0);
7626                n = Bits32 (opcode, 5, 3);
7627                m = Bits32 (opcode, 8, 6);
7628
7629                // index = TRUE; add = TRUE; wback = FALSE;
7630                index = true;
7631                add = true;
7632                wback = false;
7633
7634                // (shift_t, shift_n) = (SRType_LSL, 0);
7635                shift_t = SRType_LSL;
7636                shift_n = 0;
7637
7638                break;
7639
7640            case eEncodingT2:
7641                // if Rn == '1111' then SEE LDRSH (literal);
7642                // if Rt == '1111' then SEE "Unallocated memory hints";
7643                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7644                t = Bits32 (opcode, 15, 12);
7645                n = Bits32 (opcode, 19, 16);
7646                m = Bits32 (opcode, 3, 0);
7647
7648                // index = TRUE; add = TRUE; wback = FALSE;
7649                index = true;
7650                add = true;
7651                wback = false;
7652
7653                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7654                shift_t = SRType_LSL;
7655                shift_n = Bits32 (opcode, 5, 4);
7656
7657                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7658                if ((t == 13) || BadReg (m))
7659                    return false;
7660
7661                break;
7662
7663            case eEncodingA1:
7664                // if P == '0' && W == '1' then SEE LDRSHT;
7665                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7666                t = Bits32 (opcode, 15, 12);
7667                n = Bits32 (opcode, 19, 16);
7668                m = Bits32 (opcode, 3, 0);
7669
7670                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7671                index = BitIsSet (opcode, 24);
7672                add = BitIsSet (opcode, 23);
7673                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7674
7675                // (shift_t, shift_n) = (SRType_LSL, 0);
7676                shift_t = SRType_LSL;
7677                shift_n = 0;
7678
7679                // if t == 15 || m == 15 then UNPREDICTABLE;
7680                if ((t == 15) || (m == 15))
7681                    return false;
7682
7683                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7684                if (wback && ((n == 15) || (n == t)))
7685                    return false;
7686
7687                break;
7688
7689            default:
7690                return false;
7691        }
7692
7693        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7694        if (!success)
7695            return false;
7696
7697        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7698        if (!success)
7699            return false;
7700
7701        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7702        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7703        if (!success)
7704            return false;
7705
7706        addr_t offset_addr;
7707        addr_t address;
7708
7709        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7710        if (add)
7711            offset_addr = Rn + offset;
7712        else
7713            offset_addr = Rn - offset;
7714
7715        // address = if index then offset_addr else R[n];
7716        if (index)
7717            address = offset_addr;
7718        else
7719            address = Rn;
7720
7721        // data = MemU[address,2];
7722        RegisterInfo base_reg;
7723        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7724
7725        RegisterInfo offset_reg;
7726        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7727
7728        EmulateInstruction::Context context;
7729        context.type = eContextRegisterLoad;
7730        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7731
7732        uint64_t data = MemURead (context, address, 2, 0, &success);
7733        if (!success)
7734            return false;
7735
7736        // if wback then R[n] = offset_addr;
7737        if (wback)
7738        {
7739            context.type = eContextAdjustBaseRegister;
7740            context.SetAddress (offset_addr);
7741            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7742                return false;
7743        }
7744
7745        // if UnalignedSupport() || address<0> = '0' then
7746        if (UnalignedSupport() || BitIsClear (address, 0))
7747        {
7748            // R[t] = SignExtend(data, 32);
7749            context.type = eContextRegisterLoad;
7750            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7751
7752            int64_t signed_data = llvm::SignExtend64<16>(data);
7753            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7754                return false;
7755        }
7756        else // Can only apply before ARMv7
7757        {
7758            // R[t] = bits(32) UNKNOWN;
7759            WriteBits32Unknown (t);
7760        }
7761    }
7762    return true;
7763}
7764
7765// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7766// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7767bool
7768EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7769{
7770#if 0
7771    if ConditionPassed() then
7772        EncodingSpecificOperations();
7773        rotated = ROR(R[m], rotation);
7774        R[d] = SignExtend(rotated<7:0>, 32);
7775#endif
7776
7777    bool success = false;
7778
7779    if (ConditionPassed(opcode))
7780    {
7781        uint32_t d;
7782        uint32_t m;
7783        uint32_t rotation;
7784
7785        // EncodingSpecificOperations();
7786        switch (encoding)
7787        {
7788            case eEncodingT1:
7789                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7790                d = Bits32 (opcode, 2, 0);
7791                m = Bits32 (opcode, 5, 3);
7792                rotation = 0;
7793
7794                break;
7795
7796            case eEncodingT2:
7797                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7798                d = Bits32 (opcode, 11, 8);
7799                m = Bits32 (opcode, 3, 0);
7800                rotation = Bits32 (opcode, 5, 4) << 3;
7801
7802                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7803                if (BadReg (d) || BadReg (m))
7804                    return false;
7805
7806                break;
7807
7808            case eEncodingA1:
7809                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7810                d = Bits32 (opcode, 15, 12);
7811                m = Bits32 (opcode, 3, 0);
7812                rotation = Bits32 (opcode, 11, 10) << 3;
7813
7814                // if d == 15 || m == 15 then UNPREDICTABLE;
7815                if ((d == 15) || (m == 15))
7816                    return false;
7817
7818                break;
7819
7820            default:
7821                return false;
7822        }
7823
7824        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7825        if (!success)
7826            return false;
7827
7828        // rotated = ROR(R[m], rotation);
7829        uint64_t rotated = ROR (Rm, rotation, &success);
7830        if (!success)
7831            return false;
7832
7833        // R[d] = SignExtend(rotated<7:0>, 32);
7834        int64_t data = llvm::SignExtend64<8>(rotated);
7835
7836        RegisterInfo source_reg;
7837        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7838
7839        EmulateInstruction::Context context;
7840        context.type = eContextRegisterLoad;
7841        context.SetRegister (source_reg);
7842
7843        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7844            return false;
7845    }
7846    return true;
7847}
7848
7849// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7850// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7851bool
7852EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7853{
7854#if 0
7855    if ConditionPassed() then
7856        EncodingSpecificOperations();
7857        rotated = ROR(R[m], rotation);
7858        R[d] = SignExtend(rotated<15:0>, 32);
7859#endif
7860
7861    bool success = false;
7862
7863    if (ConditionPassed(opcode))
7864    {
7865        uint32_t d;
7866        uint32_t m;
7867        uint32_t rotation;
7868
7869        // EncodingSpecificOperations();
7870        switch (encoding)
7871        {
7872            case eEncodingT1:
7873                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7874                d = Bits32 (opcode, 2, 0);
7875                m = Bits32 (opcode, 5, 3);
7876                rotation = 0;
7877
7878                break;
7879
7880            case eEncodingT2:
7881                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7882                d = Bits32 (opcode, 11, 8);
7883                m = Bits32 (opcode, 3, 0);
7884                rotation = Bits32 (opcode, 5, 4) << 3;
7885
7886                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7887                if (BadReg (d) || BadReg (m))
7888                    return false;
7889
7890                break;
7891
7892            case eEncodingA1:
7893                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7894                d = Bits32 (opcode, 15, 12);
7895                m = Bits32 (opcode, 3, 0);
7896                rotation = Bits32 (opcode, 11, 10) << 3;
7897
7898                // if d == 15 || m == 15 then UNPREDICTABLE;
7899                if ((d == 15) || (m == 15))
7900                    return false;
7901
7902                break;
7903
7904            default:
7905                return false;
7906        }
7907
7908        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7909        if (!success)
7910            return false;
7911
7912        // rotated = ROR(R[m], rotation);
7913        uint64_t rotated = ROR (Rm, rotation, &success);
7914        if (!success)
7915            return false;
7916
7917        // R[d] = SignExtend(rotated<15:0>, 32);
7918        RegisterInfo source_reg;
7919        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7920
7921        EmulateInstruction::Context context;
7922        context.type = eContextRegisterLoad;
7923        context.SetRegister (source_reg);
7924
7925        int64_t data = llvm::SignExtend64<16> (rotated);
7926        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7927            return false;
7928    }
7929
7930    return true;
7931}
7932
7933// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7934// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7935bool
7936EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7937{
7938#if 0
7939    if ConditionPassed() then
7940        EncodingSpecificOperations();
7941        rotated = ROR(R[m], rotation);
7942        R[d] = ZeroExtend(rotated<7:0>, 32);
7943#endif
7944
7945    bool success = false;
7946
7947    if (ConditionPassed(opcode))
7948    {
7949        uint32_t d;
7950        uint32_t m;
7951        uint32_t rotation;
7952
7953        // EncodingSpecificOperations();
7954        switch (encoding)
7955        {
7956            case eEncodingT1:
7957                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7958                d = Bits32 (opcode, 2, 0);
7959                m = Bits32 (opcode, 5, 3);
7960                rotation = 0;
7961
7962                break;
7963
7964            case eEncodingT2:
7965                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7966                d = Bits32 (opcode, 11, 8);
7967                m = Bits32 (opcode, 3, 0);
7968                  rotation = Bits32 (opcode, 5, 4) << 3;
7969
7970                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7971                if (BadReg (d) || BadReg (m))
7972                  return false;
7973
7974                break;
7975
7976            case eEncodingA1:
7977                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7978                d = Bits32 (opcode, 15, 12);
7979                m = Bits32 (opcode, 3, 0);
7980                rotation = Bits32 (opcode, 11, 10) << 3;
7981
7982                // if d == 15 || m == 15 then UNPREDICTABLE;
7983                if ((d == 15) || (m == 15))
7984                    return false;
7985
7986                break;
7987
7988            default:
7989                return false;
7990        }
7991
7992        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7993        if (!success)
7994            return false;
7995
7996        // rotated = ROR(R[m], rotation);
7997        uint64_t rotated = ROR (Rm, rotation, &success);
7998        if (!success)
7999            return false;
8000
8001        // R[d] = ZeroExtend(rotated<7:0>, 32);
8002        RegisterInfo source_reg;
8003        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8004
8005        EmulateInstruction::Context context;
8006        context.type = eContextRegisterLoad;
8007        context.SetRegister (source_reg);
8008
8009        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8010            return false;
8011    }
8012    return true;
8013}
8014
8015// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8016// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8017bool
8018EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8019{
8020#if 0
8021    if ConditionPassed() then
8022        EncodingSpecificOperations();
8023        rotated = ROR(R[m], rotation);
8024        R[d] = ZeroExtend(rotated<15:0>, 32);
8025#endif
8026
8027    bool success = false;
8028
8029    if (ConditionPassed(opcode))
8030    {
8031        uint32_t d;
8032        uint32_t m;
8033        uint32_t rotation;
8034
8035        switch (encoding)
8036        {
8037            case eEncodingT1:
8038                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8039                d = Bits32 (opcode, 2, 0);
8040                m = Bits32 (opcode, 5, 3);
8041                rotation = 0;
8042
8043                break;
8044
8045            case eEncodingT2:
8046                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8047                d = Bits32 (opcode, 11, 8);
8048                m = Bits32 (opcode, 3, 0);
8049                rotation = Bits32 (opcode, 5, 4) << 3;
8050
8051                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8052                if (BadReg (d) || BadReg (m))
8053                  return false;
8054
8055                break;
8056
8057            case eEncodingA1:
8058                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8059                d = Bits32 (opcode, 15, 12);
8060                m = Bits32 (opcode, 3, 0);
8061                rotation = Bits32 (opcode, 11, 10) << 3;
8062
8063                // if d == 15 || m == 15 then UNPREDICTABLE;
8064                if ((d == 15) || (m == 15))
8065                    return false;
8066
8067                break;
8068
8069            default:
8070                return false;
8071        }
8072
8073        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8074        if (!success)
8075            return false;
8076
8077        // rotated = ROR(R[m], rotation);
8078        uint64_t rotated = ROR (Rm, rotation, &success);
8079        if (!success)
8080            return false;
8081
8082        // R[d] = ZeroExtend(rotated<15:0>, 32);
8083        RegisterInfo source_reg;
8084        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8085
8086        EmulateInstruction::Context context;
8087        context.type = eContextRegisterLoad;
8088        context.SetRegister (source_reg);
8089
8090        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8091            return false;
8092    }
8093    return true;
8094}
8095
8096// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8097// word respectively.
8098bool
8099EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8100{
8101#if 0
8102    if ConditionPassed() then
8103        EncodingSpecificOperations();
8104        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8105            UNPREDICTABLE;
8106        else
8107            address = if increment then R[n] else R[n]-8;
8108            if wordhigher then address = address+4;
8109            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8110            BranchWritePC(MemA[address,4]);
8111            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8112#endif
8113
8114    bool success = false;
8115
8116    if (ConditionPassed(opcode))
8117    {
8118        uint32_t n;
8119        bool wback;
8120        bool increment;
8121        bool wordhigher;
8122
8123        // EncodingSpecificOperations();
8124        switch (encoding)
8125        {
8126            case eEncodingT1:
8127                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8128                n = Bits32 (opcode, 19, 16);
8129                wback = BitIsSet (opcode, 21);
8130                increment = false;
8131                wordhigher = false;
8132
8133                // if n == 15 then UNPREDICTABLE;
8134                if (n == 15)
8135                    return false;
8136
8137                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8138                if (InITBlock() && !LastInITBlock())
8139                    return false;
8140
8141                break;
8142
8143            case eEncodingT2:
8144                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8145                n = Bits32 (opcode, 19, 16);
8146                wback = BitIsSet (opcode, 21);
8147                increment = true;
8148                wordhigher = false;
8149
8150                // if n == 15 then UNPREDICTABLE;
8151                if (n == 15)
8152                    return false;
8153
8154                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8155                if (InITBlock() && !LastInITBlock())
8156                    return false;
8157
8158                break;
8159
8160            case eEncodingA1:
8161                // n = UInt(Rn);
8162                n = Bits32 (opcode, 19, 16);
8163
8164                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8165                wback = BitIsSet (opcode, 21);
8166                increment = BitIsSet (opcode, 23);
8167                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8168
8169                // if n == 15 then UNPREDICTABLE;
8170                if (n == 15)
8171                    return false;
8172
8173                break;
8174
8175            default:
8176                return false;
8177        }
8178
8179        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8180        if (!CurrentModeIsPrivileged ())
8181            // UNPREDICTABLE;
8182            return false;
8183        else
8184        {
8185            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8186            if (!success)
8187                return false;
8188
8189            addr_t address;
8190            // address = if increment then R[n] else R[n]-8;
8191            if (increment)
8192                address = Rn;
8193            else
8194                address = Rn - 8;
8195
8196            // if wordhigher then address = address+4;
8197            if (wordhigher)
8198                address = address + 4;
8199
8200            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8201            RegisterInfo base_reg;
8202            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8203
8204            EmulateInstruction::Context context;
8205            context.type = eContextReturnFromException;
8206            context.SetRegisterPlusOffset (base_reg, address - Rn);
8207
8208            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8209            if (!success)
8210                return false;
8211
8212            CPSRWriteByInstr (data, 15, true);
8213
8214            // BranchWritePC(MemA[address,4]);
8215            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8216            if (!success)
8217                return false;
8218
8219            BranchWritePC (context, data2);
8220
8221            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8222            if (wback)
8223            {
8224                context.type = eContextAdjustBaseRegister;
8225                if (increment)
8226                {
8227                    context.SetOffset (8);
8228                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8229                        return false;
8230                }
8231                else
8232                {
8233                    context.SetOffset (-8);
8234                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8235                        return false;
8236                }
8237            } // if wback
8238        }
8239    } // if ConditionPassed()
8240    return true;
8241}
8242
8243// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8244// and writes the result to the destination register.  It can optionally update the condition flags based on
8245// the result.
8246bool
8247EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8248{
8249#if 0
8250    // ARM pseudo code...
8251    if ConditionPassed() then
8252        EncodingSpecificOperations();
8253        result = R[n] EOR imm32;
8254        if d == 15 then         // Can only occur for ARM encoding
8255            ALUWritePC(result); // setflags is always FALSE here
8256        else
8257            R[d] = result;
8258            if setflags then
8259                APSR.N = result<31>;
8260                APSR.Z = IsZeroBit(result);
8261                APSR.C = carry;
8262                // APSR.V unchanged
8263#endif
8264
8265    bool success = false;
8266
8267    if (ConditionPassed(opcode))
8268    {
8269        uint32_t Rd, Rn;
8270        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8271        bool setflags;
8272        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8273        switch (encoding)
8274        {
8275        case eEncodingT1:
8276            Rd = Bits32(opcode, 11, 8);
8277            Rn = Bits32(opcode, 19, 16);
8278            setflags = BitIsSet(opcode, 20);
8279            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8280            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8281            if (Rd == 15 && setflags)
8282                return EmulateTEQImm (opcode, eEncodingT1);
8283            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8284                return false;
8285            break;
8286        case eEncodingA1:
8287            Rd = Bits32(opcode, 15, 12);
8288            Rn = Bits32(opcode, 19, 16);
8289            setflags = BitIsSet(opcode, 20);
8290            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8291
8292            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8293            if (Rd == 15 && setflags)
8294                return EmulateSUBSPcLrEtc (opcode, encoding);
8295            break;
8296        default:
8297            return false;
8298        }
8299
8300        // Read the first operand.
8301        uint32_t val1 = ReadCoreReg(Rn, &success);
8302        if (!success)
8303            return false;
8304
8305        uint32_t result = val1 ^ imm32;
8306
8307        EmulateInstruction::Context context;
8308        context.type = EmulateInstruction::eContextImmediate;
8309        context.SetNoArgs ();
8310
8311        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8312            return false;
8313    }
8314    return true;
8315}
8316
8317// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8318// optionally-shifted register value, and writes the result to the destination register.
8319// It can optionally update the condition flags based on the result.
8320bool
8321EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8322{
8323#if 0
8324    // ARM pseudo code...
8325    if ConditionPassed() then
8326        EncodingSpecificOperations();
8327        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8328        result = R[n] EOR shifted;
8329        if d == 15 then         // Can only occur for ARM encoding
8330            ALUWritePC(result); // setflags is always FALSE here
8331        else
8332            R[d] = result;
8333            if setflags then
8334                APSR.N = result<31>;
8335                APSR.Z = IsZeroBit(result);
8336                APSR.C = carry;
8337                // APSR.V unchanged
8338#endif
8339
8340    bool success = false;
8341
8342    if (ConditionPassed(opcode))
8343    {
8344        uint32_t Rd, Rn, Rm;
8345        ARM_ShifterType shift_t;
8346        uint32_t shift_n; // the shift applied to the value read from Rm
8347        bool setflags;
8348        uint32_t carry;
8349        switch (encoding)
8350        {
8351        case eEncodingT1:
8352            Rd = Rn = Bits32(opcode, 2, 0);
8353            Rm = Bits32(opcode, 5, 3);
8354            setflags = !InITBlock();
8355            shift_t = SRType_LSL;
8356            shift_n = 0;
8357            break;
8358        case eEncodingT2:
8359            Rd = Bits32(opcode, 11, 8);
8360            Rn = Bits32(opcode, 19, 16);
8361            Rm = Bits32(opcode, 3, 0);
8362            setflags = BitIsSet(opcode, 20);
8363            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8364            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8365            if (Rd == 15 && setflags)
8366                return EmulateTEQReg (opcode, eEncodingT1);
8367            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8368                return false;
8369            break;
8370        case eEncodingA1:
8371            Rd = Bits32(opcode, 15, 12);
8372            Rn = Bits32(opcode, 19, 16);
8373            Rm = Bits32(opcode, 3, 0);
8374            setflags = BitIsSet(opcode, 20);
8375            shift_n = DecodeImmShiftARM(opcode, shift_t);
8376
8377            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8378            if (Rd == 15 && setflags)
8379                return EmulateSUBSPcLrEtc (opcode, encoding);
8380            break;
8381        default:
8382            return false;
8383        }
8384
8385        // Read the first operand.
8386        uint32_t val1 = ReadCoreReg(Rn, &success);
8387        if (!success)
8388            return false;
8389
8390        // Read the second operand.
8391        uint32_t val2 = ReadCoreReg(Rm, &success);
8392        if (!success)
8393            return false;
8394
8395        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8396        if (!success)
8397            return false;
8398        uint32_t result = val1 ^ shifted;
8399
8400        EmulateInstruction::Context context;
8401        context.type = EmulateInstruction::eContextImmediate;
8402        context.SetNoArgs ();
8403
8404        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8405            return false;
8406    }
8407    return true;
8408}
8409
8410// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8411// writes the result to the destination register.  It can optionally update the condition flags based
8412// on the result.
8413bool
8414EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8415{
8416#if 0
8417    // ARM pseudo code...
8418    if ConditionPassed() then
8419        EncodingSpecificOperations();
8420        result = R[n] OR imm32;
8421        if d == 15 then         // Can only occur for ARM encoding
8422            ALUWritePC(result); // setflags is always FALSE here
8423        else
8424            R[d] = result;
8425            if setflags then
8426                APSR.N = result<31>;
8427                APSR.Z = IsZeroBit(result);
8428                APSR.C = carry;
8429                // APSR.V unchanged
8430#endif
8431
8432    bool success = false;
8433
8434    if (ConditionPassed(opcode))
8435    {
8436        uint32_t Rd, Rn;
8437        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8438        bool setflags;
8439        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8440        switch (encoding)
8441        {
8442        case eEncodingT1:
8443            Rd = Bits32(opcode, 11, 8);
8444            Rn = Bits32(opcode, 19, 16);
8445            setflags = BitIsSet(opcode, 20);
8446            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8447            // if Rn == '1111' then SEE MOV (immediate);
8448            if (Rn == 15)
8449                return EmulateMOVRdImm (opcode, eEncodingT2);
8450            if (BadReg(Rd) || Rn == 13)
8451                return false;
8452            break;
8453        case eEncodingA1:
8454            Rd = Bits32(opcode, 15, 12);
8455            Rn = Bits32(opcode, 19, 16);
8456            setflags = BitIsSet(opcode, 20);
8457            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8458
8459            if (Rd == 15 && setflags)
8460                return EmulateSUBSPcLrEtc (opcode, encoding);
8461            break;
8462        default:
8463            return false;
8464        }
8465
8466        // Read the first operand.
8467        uint32_t val1 = ReadCoreReg(Rn, &success);
8468        if (!success)
8469            return false;
8470
8471        uint32_t result = val1 | imm32;
8472
8473        EmulateInstruction::Context context;
8474        context.type = EmulateInstruction::eContextImmediate;
8475        context.SetNoArgs ();
8476
8477        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8478            return false;
8479    }
8480    return true;
8481}
8482
8483// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8484// value, and writes the result to the destination register.  It can optionally update the condition flags based
8485// on the result.
8486bool
8487EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8488{
8489#if 0
8490    // ARM pseudo code...
8491    if ConditionPassed() then
8492        EncodingSpecificOperations();
8493        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8494        result = R[n] OR shifted;
8495        if d == 15 then         // Can only occur for ARM encoding
8496            ALUWritePC(result); // setflags is always FALSE here
8497        else
8498            R[d] = result;
8499            if setflags then
8500                APSR.N = result<31>;
8501                APSR.Z = IsZeroBit(result);
8502                APSR.C = carry;
8503                // APSR.V unchanged
8504#endif
8505
8506    bool success = false;
8507
8508    if (ConditionPassed(opcode))
8509    {
8510        uint32_t Rd, Rn, Rm;
8511        ARM_ShifterType shift_t;
8512        uint32_t shift_n; // the shift applied to the value read from Rm
8513        bool setflags;
8514        uint32_t carry;
8515        switch (encoding)
8516        {
8517        case eEncodingT1:
8518            Rd = Rn = Bits32(opcode, 2, 0);
8519            Rm = Bits32(opcode, 5, 3);
8520            setflags = !InITBlock();
8521            shift_t = SRType_LSL;
8522            shift_n = 0;
8523            break;
8524        case eEncodingT2:
8525            Rd = Bits32(opcode, 11, 8);
8526            Rn = Bits32(opcode, 19, 16);
8527            Rm = Bits32(opcode, 3, 0);
8528            setflags = BitIsSet(opcode, 20);
8529            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8530            // if Rn == '1111' then SEE MOV (register);
8531            if (Rn == 15)
8532                return EmulateMOVRdRm (opcode, eEncodingT3);
8533            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8534                return false;
8535            break;
8536        case eEncodingA1:
8537            Rd = Bits32(opcode, 15, 12);
8538            Rn = Bits32(opcode, 19, 16);
8539            Rm = Bits32(opcode, 3, 0);
8540            setflags = BitIsSet(opcode, 20);
8541            shift_n = DecodeImmShiftARM(opcode, shift_t);
8542
8543            if (Rd == 15 && setflags)
8544                return EmulateSUBSPcLrEtc (opcode, encoding);
8545            break;
8546        default:
8547            return false;
8548        }
8549
8550        // Read the first operand.
8551        uint32_t val1 = ReadCoreReg(Rn, &success);
8552        if (!success)
8553            return false;
8554
8555        // Read the second operand.
8556        uint32_t val2 = ReadCoreReg(Rm, &success);
8557        if (!success)
8558            return false;
8559
8560        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8561        if (!success)
8562            return false;
8563        uint32_t result = val1 | shifted;
8564
8565        EmulateInstruction::Context context;
8566        context.type = EmulateInstruction::eContextImmediate;
8567        context.SetNoArgs ();
8568
8569        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8570            return false;
8571    }
8572    return true;
8573}
8574
8575// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8576// the destination register. It can optionally update the condition flags based on the result.
8577bool
8578EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8579{
8580#if 0
8581    // ARM pseudo code...
8582    if ConditionPassed() then
8583        EncodingSpecificOperations();
8584        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8585        if d == 15 then         // Can only occur for ARM encoding
8586            ALUWritePC(result); // setflags is always FALSE here
8587        else
8588            R[d] = result;
8589            if setflags then
8590                APSR.N = result<31>;
8591                APSR.Z = IsZeroBit(result);
8592                APSR.C = carry;
8593                APSR.V = overflow;
8594#endif
8595
8596    bool success = false;
8597
8598    uint32_t Rd; // the destination register
8599    uint32_t Rn; // the first operand
8600    bool setflags;
8601    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8602    switch (encoding) {
8603    case eEncodingT1:
8604        Rd = Bits32(opcode, 2, 0);
8605        Rn = Bits32(opcode, 5, 3);
8606        setflags = !InITBlock();
8607        imm32 = 0;
8608        break;
8609    case eEncodingT2:
8610        Rd = Bits32(opcode, 11, 8);
8611        Rn = Bits32(opcode, 19, 16);
8612        setflags = BitIsSet(opcode, 20);
8613        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8614        if (BadReg(Rd) || BadReg(Rn))
8615            return false;
8616        break;
8617    case eEncodingA1:
8618        Rd = Bits32(opcode, 15, 12);
8619        Rn = Bits32(opcode, 19, 16);
8620        setflags = BitIsSet(opcode, 20);
8621        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8622
8623        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8624        if (Rd == 15 && setflags)
8625            return EmulateSUBSPcLrEtc (opcode, encoding);
8626        break;
8627    default:
8628        return false;
8629    }
8630    // Read the register value from the operand register Rn.
8631    uint32_t reg_val = ReadCoreReg(Rn, &success);
8632    if (!success)
8633        return false;
8634
8635    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8636
8637    EmulateInstruction::Context context;
8638    context.type = EmulateInstruction::eContextImmediate;
8639    context.SetNoArgs ();
8640
8641    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8642        return false;
8643
8644    return true;
8645}
8646
8647// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8648// result to the destination register. It can optionally update the condition flags based on the result.
8649bool
8650EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8651{
8652#if 0
8653    // ARM pseudo code...
8654    if ConditionPassed() then
8655        EncodingSpecificOperations();
8656        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8657        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8658        if d == 15 then         // Can only occur for ARM encoding
8659            ALUWritePC(result); // setflags is always FALSE here
8660        else
8661            R[d] = result;
8662            if setflags then
8663                APSR.N = result<31>;
8664                APSR.Z = IsZeroBit(result);
8665                APSR.C = carry;
8666                APSR.V = overflow;
8667#endif
8668
8669    bool success = false;
8670
8671    uint32_t Rd; // the destination register
8672    uint32_t Rn; // the first operand
8673    uint32_t Rm; // the second operand
8674    bool setflags;
8675    ARM_ShifterType shift_t;
8676    uint32_t shift_n; // the shift applied to the value read from Rm
8677    switch (encoding) {
8678    case eEncodingT1:
8679        Rd = Bits32(opcode, 11, 8);
8680        Rn = Bits32(opcode, 19, 16);
8681        Rm = Bits32(opcode, 3, 0);
8682        setflags = BitIsSet(opcode, 20);
8683        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8684        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8685        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8686            return false;
8687        break;
8688    case eEncodingA1:
8689        Rd = Bits32(opcode, 15, 12);
8690        Rn = Bits32(opcode, 19, 16);
8691        Rm = Bits32(opcode, 3, 0);
8692        setflags = BitIsSet(opcode, 20);
8693        shift_n = DecodeImmShiftARM(opcode, shift_t);
8694
8695        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8696        if (Rd == 15 && setflags)
8697            return EmulateSUBSPcLrEtc (opcode, encoding);
8698        break;
8699    default:
8700        return false;
8701    }
8702    // Read the register value from register Rn.
8703    uint32_t val1 = ReadCoreReg(Rn, &success);
8704    if (!success)
8705        return false;
8706
8707    // Read the register value from register Rm.
8708    uint32_t val2 = ReadCoreReg(Rm, &success);
8709    if (!success)
8710        return false;
8711
8712    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8713    if (!success)
8714        return false;
8715    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8716
8717    EmulateInstruction::Context context;
8718    context.type = EmulateInstruction::eContextImmediate;
8719    context.SetNoArgs();
8720    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8721        return false;
8722
8723    return true;
8724}
8725
8726// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8727// an immediate value, and writes the result to the destination register. It can optionally update the condition
8728// flags based on the result.
8729bool
8730EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8731{
8732#if 0
8733    // ARM pseudo code...
8734    if ConditionPassed() then
8735        EncodingSpecificOperations();
8736        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8737        if d == 15 then
8738            ALUWritePC(result); // setflags is always FALSE here
8739        else
8740            R[d] = result;
8741            if setflags then
8742                APSR.N = result<31>;
8743                APSR.Z = IsZeroBit(result);
8744                APSR.C = carry;
8745                APSR.V = overflow;
8746#endif
8747
8748    bool success = false;
8749
8750    uint32_t Rd; // the destination register
8751    uint32_t Rn; // the first operand
8752    bool setflags;
8753    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8754    switch (encoding) {
8755    case eEncodingA1:
8756        Rd = Bits32(opcode, 15, 12);
8757        Rn = Bits32(opcode, 19, 16);
8758        setflags = BitIsSet(opcode, 20);
8759        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8760
8761        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8762        if (Rd == 15 && setflags)
8763            return EmulateSUBSPcLrEtc  (opcode, encoding);
8764        break;
8765    default:
8766        return false;
8767    }
8768    // Read the register value from the operand register Rn.
8769    uint32_t reg_val = ReadCoreReg(Rn, &success);
8770    if (!success)
8771        return false;
8772
8773    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8774
8775    EmulateInstruction::Context context;
8776    context.type = EmulateInstruction::eContextImmediate;
8777    context.SetNoArgs ();
8778
8779    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8780        return false;
8781
8782    return true;
8783}
8784
8785// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8786// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8787// condition flags based on the result.
8788bool
8789EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8790{
8791#if 0
8792    // ARM pseudo code...
8793    if ConditionPassed() then
8794        EncodingSpecificOperations();
8795        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8796        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8797        if d == 15 then
8798            ALUWritePC(result); // setflags is always FALSE here
8799        else
8800            R[d] = result;
8801            if setflags then
8802                APSR.N = result<31>;
8803                APSR.Z = IsZeroBit(result);
8804                APSR.C = carry;
8805                APSR.V = overflow;
8806#endif
8807
8808    bool success = false;
8809
8810    uint32_t Rd; // the destination register
8811    uint32_t Rn; // the first operand
8812    uint32_t Rm; // the second operand
8813    bool setflags;
8814    ARM_ShifterType shift_t;
8815    uint32_t shift_n; // the shift applied to the value read from Rm
8816    switch (encoding) {
8817    case eEncodingA1:
8818        Rd = Bits32(opcode, 15, 12);
8819        Rn = Bits32(opcode, 19, 16);
8820        Rm = Bits32(opcode, 3, 0);
8821        setflags = BitIsSet(opcode, 20);
8822        shift_n = DecodeImmShiftARM(opcode, shift_t);
8823
8824        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8825        if (Rd == 15 && setflags)
8826            return EmulateSUBSPcLrEtc (opcode, encoding);
8827        break;
8828    default:
8829        return false;
8830    }
8831    // Read the register value from register Rn.
8832    uint32_t val1 = ReadCoreReg(Rn, &success);
8833    if (!success)
8834        return false;
8835
8836    // Read the register value from register Rm.
8837    uint32_t val2 = ReadCoreReg(Rm, &success);
8838    if (!success)
8839        return false;
8840
8841    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8842    if (!success)
8843        return false;
8844    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8845
8846    EmulateInstruction::Context context;
8847    context.type = EmulateInstruction::eContextImmediate;
8848    context.SetNoArgs();
8849    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8850        return false;
8851
8852    return true;
8853}
8854
8855// Subtract with Carry (immediate) subtracts an immediate value and the value of
8856// NOT (Carry flag) from a register value, and writes the result to the destination register.
8857// It can optionally update the condition flags based on the result.
8858bool
8859EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8860{
8861#if 0
8862    // ARM pseudo code...
8863    if ConditionPassed() then
8864        EncodingSpecificOperations();
8865        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8866        if d == 15 then         // Can only occur for ARM encoding
8867            ALUWritePC(result); // setflags is always FALSE here
8868        else
8869            R[d] = result;
8870            if setflags then
8871                APSR.N = result<31>;
8872                APSR.Z = IsZeroBit(result);
8873                APSR.C = carry;
8874                APSR.V = overflow;
8875#endif
8876
8877    bool success = false;
8878
8879    uint32_t Rd; // the destination register
8880    uint32_t Rn; // the first operand
8881    bool setflags;
8882    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8883    switch (encoding) {
8884    case eEncodingT1:
8885        Rd = Bits32(opcode, 11, 8);
8886        Rn = Bits32(opcode, 19, 16);
8887        setflags = BitIsSet(opcode, 20);
8888        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8889        if (BadReg(Rd) || BadReg(Rn))
8890            return false;
8891        break;
8892    case eEncodingA1:
8893        Rd = Bits32(opcode, 15, 12);
8894        Rn = Bits32(opcode, 19, 16);
8895        setflags = BitIsSet(opcode, 20);
8896        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8897
8898        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8899        if (Rd == 15 && setflags)
8900            return EmulateSUBSPcLrEtc (opcode, encoding);
8901        break;
8902    default:
8903        return false;
8904    }
8905    // Read the register value from the operand register Rn.
8906    uint32_t reg_val = ReadCoreReg(Rn, &success);
8907    if (!success)
8908        return false;
8909
8910    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8911
8912    EmulateInstruction::Context context;
8913    context.type = EmulateInstruction::eContextImmediate;
8914    context.SetNoArgs ();
8915
8916    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8917        return false;
8918
8919    return true;
8920}
8921
8922// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8923// NOT (Carry flag) from a register value, and writes the result to the destination register.
8924// It can optionally update the condition flags based on the result.
8925bool
8926EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8927{
8928#if 0
8929    // ARM pseudo code...
8930    if ConditionPassed() then
8931        EncodingSpecificOperations();
8932        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8933        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8934        if d == 15 then         // Can only occur for ARM encoding
8935            ALUWritePC(result); // setflags is always FALSE here
8936        else
8937            R[d] = result;
8938            if setflags then
8939                APSR.N = result<31>;
8940                APSR.Z = IsZeroBit(result);
8941                APSR.C = carry;
8942                APSR.V = overflow;
8943#endif
8944
8945    bool success = false;
8946
8947    uint32_t Rd; // the destination register
8948    uint32_t Rn; // the first operand
8949    uint32_t Rm; // the second operand
8950    bool setflags;
8951    ARM_ShifterType shift_t;
8952    uint32_t shift_n; // the shift applied to the value read from Rm
8953    switch (encoding) {
8954    case eEncodingT1:
8955        Rd = Rn = Bits32(opcode, 2, 0);
8956        Rm = Bits32(opcode, 5, 3);
8957        setflags = !InITBlock();
8958        shift_t = SRType_LSL;
8959        shift_n = 0;
8960        break;
8961    case eEncodingT2:
8962        Rd = Bits32(opcode, 11, 8);
8963        Rn = Bits32(opcode, 19, 16);
8964        Rm = Bits32(opcode, 3, 0);
8965        setflags = BitIsSet(opcode, 20);
8966        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8967        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8968            return false;
8969        break;
8970    case eEncodingA1:
8971        Rd = Bits32(opcode, 15, 12);
8972        Rn = Bits32(opcode, 19, 16);
8973        Rm = Bits32(opcode, 3, 0);
8974        setflags = BitIsSet(opcode, 20);
8975        shift_n = DecodeImmShiftARM(opcode, shift_t);
8976
8977        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8978        if (Rd == 15 && setflags)
8979            return EmulateSUBSPcLrEtc (opcode, encoding);
8980        break;
8981    default:
8982        return false;
8983    }
8984    // Read the register value from register Rn.
8985    uint32_t val1 = ReadCoreReg(Rn, &success);
8986    if (!success)
8987        return false;
8988
8989    // Read the register value from register Rm.
8990    uint32_t val2 = ReadCoreReg(Rm, &success);
8991    if (!success)
8992        return false;
8993
8994    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8995    if (!success)
8996        return false;
8997    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8998
8999    EmulateInstruction::Context context;
9000    context.type = EmulateInstruction::eContextImmediate;
9001    context.SetNoArgs();
9002    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9003        return false;
9004
9005    return true;
9006}
9007
9008// This instruction subtracts an immediate value from a register value, and writes the result
9009// to the destination register.  It can optionally update the condition flags based on the result.
9010bool
9011EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9012{
9013#if 0
9014    // ARM pseudo code...
9015    if ConditionPassed() then
9016        EncodingSpecificOperations();
9017        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9018        R[d] = result;
9019        if setflags then
9020            APSR.N = result<31>;
9021            APSR.Z = IsZeroBit(result);
9022            APSR.C = carry;
9023            APSR.V = overflow;
9024#endif
9025
9026    bool success = false;
9027
9028    uint32_t Rd; // the destination register
9029    uint32_t Rn; // the first operand
9030    bool setflags;
9031    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9032    switch (encoding) {
9033    case eEncodingT1:
9034        Rd = Bits32(opcode, 2, 0);
9035        Rn = Bits32(opcode, 5, 3);
9036        setflags = !InITBlock();
9037        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9038        break;
9039    case eEncodingT2:
9040        Rd = Rn = Bits32(opcode, 10, 8);
9041        setflags = !InITBlock();
9042        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9043        break;
9044    case eEncodingT3:
9045        Rd = Bits32(opcode, 11, 8);
9046        Rn = Bits32(opcode, 19, 16);
9047        setflags = BitIsSet(opcode, 20);
9048        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9049
9050        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9051        if (Rd == 15 && setflags)
9052            return EmulateCMPImm (opcode, eEncodingT2);
9053
9054        // if Rn == '1101' then SEE SUB (SP minus immediate);
9055        if (Rn == 13)
9056            return EmulateSUBSPImm (opcode, eEncodingT2);
9057
9058        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9059        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9060            return false;
9061        break;
9062    case eEncodingT4:
9063        Rd = Bits32(opcode, 11, 8);
9064        Rn = Bits32(opcode, 19, 16);
9065        setflags = BitIsSet(opcode, 20);
9066        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9067
9068        // if Rn == '1111' then SEE ADR;
9069        if (Rn == 15)
9070            return EmulateADR (opcode, eEncodingT2);
9071
9072        // if Rn == '1101' then SEE SUB (SP minus immediate);
9073        if (Rn == 13)
9074            return EmulateSUBSPImm (opcode, eEncodingT3);
9075
9076        if (BadReg(Rd))
9077            return false;
9078        break;
9079    default:
9080        return false;
9081    }
9082    // Read the register value from the operand register Rn.
9083    uint32_t reg_val = ReadCoreReg(Rn, &success);
9084    if (!success)
9085        return false;
9086
9087    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9088
9089    EmulateInstruction::Context context;
9090    context.type = EmulateInstruction::eContextImmediate;
9091    context.SetNoArgs ();
9092
9093    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9094        return false;
9095
9096    return true;
9097}
9098
9099// This instruction subtracts an immediate value from a register value, and writes the result
9100// to the destination register.  It can optionally update the condition flags based on the result.
9101bool
9102EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9103{
9104#if 0
9105    // ARM pseudo code...
9106    if ConditionPassed() then
9107        EncodingSpecificOperations();
9108        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9109        if d == 15 then
9110            ALUWritePC(result); // setflags is always FALSE here
9111        else
9112            R[d] = result;
9113            if setflags then
9114                APSR.N = result<31>;
9115                APSR.Z = IsZeroBit(result);
9116                APSR.C = carry;
9117                APSR.V = overflow;
9118#endif
9119
9120    bool success = false;
9121
9122    uint32_t Rd; // the destination register
9123    uint32_t Rn; // the first operand
9124    bool setflags;
9125    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9126    switch (encoding) {
9127    case eEncodingA1:
9128        Rd = Bits32(opcode, 15, 12);
9129        Rn = Bits32(opcode, 19, 16);
9130        setflags = BitIsSet(opcode, 20);
9131        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9132
9133        // if Rn == '1111' && S == '0' then SEE ADR;
9134        if (Rn == 15 && !setflags)
9135            return EmulateADR (opcode, eEncodingA2);
9136
9137        // if Rn == '1101' then SEE SUB (SP minus immediate);
9138        if (Rn == 13)
9139            return EmulateSUBSPImm (opcode, eEncodingA1);
9140
9141        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9142        if (Rd == 15 && setflags)
9143            return EmulateSUBSPcLrEtc (opcode, encoding);
9144        break;
9145    default:
9146        return false;
9147    }
9148    // Read the register value from the operand register Rn.
9149    uint32_t reg_val = ReadCoreReg(Rn, &success);
9150    if (!success)
9151        return false;
9152
9153    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9154
9155    EmulateInstruction::Context context;
9156    context.type = EmulateInstruction::eContextImmediate;
9157    context.SetNoArgs ();
9158
9159    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9160        return false;
9161
9162    return true;
9163}
9164
9165// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9166// immediate value.  It updates the condition flags based on the result, and discards the result.
9167bool
9168EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9169{
9170#if 0
9171    // ARM pseudo code...
9172    if ConditionPassed() then
9173        EncodingSpecificOperations();
9174        result = R[n] EOR imm32;
9175        APSR.N = result<31>;
9176        APSR.Z = IsZeroBit(result);
9177        APSR.C = carry;
9178        // APSR.V unchanged
9179#endif
9180
9181    bool success = false;
9182
9183    if (ConditionPassed(opcode))
9184    {
9185        uint32_t Rn;
9186        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9187        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9188        switch (encoding)
9189        {
9190        case eEncodingT1:
9191            Rn = Bits32(opcode, 19, 16);
9192            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9193            if (BadReg(Rn))
9194                return false;
9195            break;
9196        case eEncodingA1:
9197            Rn = Bits32(opcode, 19, 16);
9198            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9199            break;
9200        default:
9201            return false;
9202        }
9203
9204        // Read the first operand.
9205        uint32_t val1 = ReadCoreReg(Rn, &success);
9206        if (!success)
9207            return false;
9208
9209        uint32_t result = val1 ^ imm32;
9210
9211        EmulateInstruction::Context context;
9212        context.type = EmulateInstruction::eContextImmediate;
9213        context.SetNoArgs ();
9214
9215        if (!WriteFlags(context, result, carry))
9216            return false;
9217    }
9218    return true;
9219}
9220
9221// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9222// optionally-shifted register value.  It updates the condition flags based on the result, and discards
9223// the result.
9224bool
9225EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9226{
9227#if 0
9228    // ARM pseudo code...
9229    if ConditionPassed() then
9230        EncodingSpecificOperations();
9231        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9232        result = R[n] EOR shifted;
9233        APSR.N = result<31>;
9234        APSR.Z = IsZeroBit(result);
9235        APSR.C = carry;
9236        // APSR.V unchanged
9237#endif
9238
9239    bool success = false;
9240
9241    if (ConditionPassed(opcode))
9242    {
9243        uint32_t Rn, Rm;
9244        ARM_ShifterType shift_t;
9245        uint32_t shift_n; // the shift applied to the value read from Rm
9246        uint32_t carry;
9247        switch (encoding)
9248        {
9249        case eEncodingT1:
9250            Rn = Bits32(opcode, 19, 16);
9251            Rm = Bits32(opcode, 3, 0);
9252            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9253            if (BadReg(Rn) || BadReg(Rm))
9254                return false;
9255            break;
9256        case eEncodingA1:
9257            Rn = Bits32(opcode, 19, 16);
9258            Rm = Bits32(opcode, 3, 0);
9259            shift_n = DecodeImmShiftARM(opcode, shift_t);
9260            break;
9261        default:
9262            return false;
9263        }
9264
9265        // Read the first operand.
9266        uint32_t val1 = ReadCoreReg(Rn, &success);
9267        if (!success)
9268            return false;
9269
9270        // Read the second operand.
9271        uint32_t val2 = ReadCoreReg(Rm, &success);
9272        if (!success)
9273            return false;
9274
9275        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9276        if (!success)
9277            return false;
9278        uint32_t result = val1 ^ shifted;
9279
9280        EmulateInstruction::Context context;
9281        context.type = EmulateInstruction::eContextImmediate;
9282        context.SetNoArgs ();
9283
9284        if (!WriteFlags(context, result, carry))
9285            return false;
9286    }
9287    return true;
9288}
9289
9290// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9291// It updates the condition flags based on the result, and discards the result.
9292bool
9293EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9294{
9295#if 0
9296    // ARM pseudo code...
9297    if ConditionPassed() then
9298        EncodingSpecificOperations();
9299        result = R[n] AND imm32;
9300        APSR.N = result<31>;
9301        APSR.Z = IsZeroBit(result);
9302        APSR.C = carry;
9303        // APSR.V unchanged
9304#endif
9305
9306    bool success = false;
9307
9308    if (ConditionPassed(opcode))
9309    {
9310        uint32_t Rn;
9311        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9312        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9313        switch (encoding)
9314        {
9315        case eEncodingT1:
9316            Rn = Bits32(opcode, 19, 16);
9317            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9318            if (BadReg(Rn))
9319                return false;
9320            break;
9321        case eEncodingA1:
9322            Rn = Bits32(opcode, 19, 16);
9323            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9324            break;
9325        default:
9326            return false;
9327        }
9328
9329        // Read the first operand.
9330        uint32_t val1 = ReadCoreReg(Rn, &success);
9331        if (!success)
9332            return false;
9333
9334        uint32_t result = val1 & imm32;
9335
9336        EmulateInstruction::Context context;
9337        context.type = EmulateInstruction::eContextImmediate;
9338        context.SetNoArgs ();
9339
9340        if (!WriteFlags(context, result, carry))
9341            return false;
9342    }
9343    return true;
9344}
9345
9346// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9347// It updates the condition flags based on the result, and discards the result.
9348bool
9349EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9350{
9351#if 0
9352    // ARM pseudo code...
9353    if ConditionPassed() then
9354        EncodingSpecificOperations();
9355        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9356        result = R[n] AND shifted;
9357        APSR.N = result<31>;
9358        APSR.Z = IsZeroBit(result);
9359        APSR.C = carry;
9360        // APSR.V unchanged
9361#endif
9362
9363    bool success = false;
9364
9365    if (ConditionPassed(opcode))
9366    {
9367        uint32_t Rn, Rm;
9368        ARM_ShifterType shift_t;
9369        uint32_t shift_n; // the shift applied to the value read from Rm
9370        uint32_t carry;
9371        switch (encoding)
9372        {
9373        case eEncodingT1:
9374            Rn = Bits32(opcode, 2, 0);
9375            Rm = Bits32(opcode, 5, 3);
9376            shift_t = SRType_LSL;
9377            shift_n = 0;
9378            break;
9379        case eEncodingT2:
9380            Rn = Bits32(opcode, 19, 16);
9381            Rm = Bits32(opcode, 3, 0);
9382            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9383            if (BadReg(Rn) || BadReg(Rm))
9384                return false;
9385            break;
9386        case eEncodingA1:
9387            Rn = Bits32(opcode, 19, 16);
9388            Rm = Bits32(opcode, 3, 0);
9389            shift_n = DecodeImmShiftARM(opcode, shift_t);
9390            break;
9391        default:
9392            return false;
9393        }
9394
9395        // Read the first operand.
9396        uint32_t val1 = ReadCoreReg(Rn, &success);
9397        if (!success)
9398            return false;
9399
9400        // Read the second operand.
9401        uint32_t val2 = ReadCoreReg(Rm, &success);
9402        if (!success)
9403            return false;
9404
9405        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9406        if (!success)
9407            return false;
9408        uint32_t result = val1 & shifted;
9409
9410        EmulateInstruction::Context context;
9411        context.type = EmulateInstruction::eContextImmediate;
9412        context.SetNoArgs ();
9413
9414        if (!WriteFlags(context, result, carry))
9415            return false;
9416    }
9417    return true;
9418}
9419
9420// A8.6.216 SUB (SP minus register)
9421bool
9422EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9423{
9424#if 0
9425    if ConditionPassed() then
9426        EncodingSpecificOperations();
9427        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9428        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9429        if d == 15 then // Can only occur for ARM encoding
9430            ALUWritePC(result); // setflags is always FALSE here
9431        else
9432            R[d] = result;
9433            if setflags then
9434                APSR.N = result<31>;
9435                APSR.Z = IsZeroBit(result);
9436                APSR.C = carry;
9437                APSR.V = overflow;
9438#endif
9439
9440    bool success = false;
9441
9442    if (ConditionPassed(opcode))
9443    {
9444        uint32_t d;
9445        uint32_t m;
9446        bool setflags;
9447        ARM_ShifterType shift_t;
9448        uint32_t shift_n;
9449
9450        switch (encoding)
9451        {
9452            case eEncodingT1:
9453                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9454                d = Bits32 (opcode, 11, 8);
9455                m = Bits32 (opcode, 3, 0);
9456                setflags = BitIsSet (opcode, 20);
9457
9458                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9459                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9460
9461                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9462                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9463                    return false;
9464
9465                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9466                if ((d == 15) || BadReg (m))
9467                    return false;
9468                break;
9469
9470            case eEncodingA1:
9471                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9472                d = Bits32 (opcode, 15, 12);
9473                m = Bits32 (opcode, 3, 0);
9474                setflags = BitIsSet (opcode, 20);
9475
9476                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9477                if (d == 15 && setflags)
9478                    EmulateSUBSPcLrEtc (opcode, encoding);
9479
9480                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9481                shift_n = DecodeImmShiftARM (opcode, shift_t);
9482                break;
9483
9484            default:
9485                return false;
9486        }
9487
9488        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9489        uint32_t Rm = ReadCoreReg (m, &success);
9490        if (!success)
9491            return false;
9492
9493        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9494        if (!success)
9495            return false;
9496
9497        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9498        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9499        if (!success)
9500            return false;
9501
9502        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9503
9504        EmulateInstruction::Context context;
9505        context.type = eContextArithmetic;
9506        RegisterInfo sp_reg;
9507        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9508        RegisterInfo dwarf_reg;
9509        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9510        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9511
9512        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9513            return false;
9514    }
9515    return true;
9516}
9517
9518
9519// A8.6.7 ADD (register-shifted register)
9520bool
9521EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9522{
9523#if 0
9524    if ConditionPassed() then
9525        EncodingSpecificOperations();
9526        shift_n = UInt(R[s]<7:0>);
9527        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9528        (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9529        R[d] = result;
9530        if setflags then
9531            APSR.N = result<31>;
9532            APSR.Z = IsZeroBit(result);
9533            APSR.C = carry;
9534            APSR.V = overflow;
9535#endif
9536
9537    bool success = false;
9538
9539    if (ConditionPassed(opcode))
9540    {
9541        uint32_t d;
9542        uint32_t n;
9543        uint32_t m;
9544        uint32_t s;
9545        bool setflags;
9546        ARM_ShifterType shift_t;
9547
9548        switch (encoding)
9549        {
9550            case eEncodingA1:
9551                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9552                d = Bits32 (opcode, 15, 12);
9553                n = Bits32 (opcode, 19, 16);
9554                m = Bits32 (opcode, 3, 0);
9555                s = Bits32 (opcode, 11, 8);
9556
9557                // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9558                setflags = BitIsSet (opcode, 20);
9559                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9560
9561                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9562                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9563                    return false;
9564                break;
9565
9566            default:
9567                return false;
9568        }
9569
9570        // shift_n = UInt(R[s]<7:0>);
9571        uint32_t Rs = ReadCoreReg (s, &success);
9572        if (!success)
9573            return false;
9574
9575        uint32_t shift_n = Bits32 (Rs, 7, 0);
9576
9577        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9578        uint32_t Rm = ReadCoreReg (m, &success);
9579        if (!success)
9580            return false;
9581
9582        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9583        if (!success)
9584            return false;
9585
9586        // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9587        uint32_t Rn = ReadCoreReg (n, &success);
9588        if (!success)
9589            return false;
9590
9591        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9592
9593        // R[d] = result;
9594        EmulateInstruction::Context context;
9595        context.type = eContextArithmetic;
9596        RegisterInfo reg_n;
9597        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9598        RegisterInfo reg_m;
9599        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9600
9601        context.SetRegisterRegisterOperands (reg_n, reg_m);
9602
9603        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9604            return false;
9605
9606        // if setflags then
9607            // APSR.N = result<31>;
9608            // APSR.Z = IsZeroBit(result);
9609            // APSR.C = carry;
9610            // APSR.V = overflow;
9611        if (setflags)
9612            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9613    }
9614    return true;
9615}
9616
9617// A8.6.213 SUB (register)
9618bool
9619EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9620{
9621#if 0
9622    if ConditionPassed() then
9623        EncodingSpecificOperations();
9624        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9625        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9626        if d == 15 then // Can only occur for ARM encoding
9627            ALUWritePC(result); // setflags is always FALSE here
9628        else
9629            R[d] = result;
9630            if setflags then
9631                APSR.N = result<31>;
9632                APSR.Z = IsZeroBit(result);
9633                APSR.C = carry;
9634                APSR.V = overflow;
9635#endif
9636
9637    bool success = false;
9638
9639    if (ConditionPassed(opcode))
9640    {
9641        uint32_t d;
9642        uint32_t n;
9643        uint32_t m;
9644        bool setflags;
9645        ARM_ShifterType shift_t;
9646        uint32_t shift_n;
9647
9648        switch (encoding)
9649        {
9650            case eEncodingT1:
9651                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9652                d = Bits32 (opcode, 2, 0);
9653                n = Bits32 (opcode, 5, 3);
9654                m = Bits32 (opcode, 8, 6);
9655                setflags = !InITBlock();
9656
9657                // (shift_t, shift_n) = (SRType_LSL, 0);
9658                shift_t = SRType_LSL;
9659                shift_n = 0;
9660
9661                break;
9662
9663            case eEncodingT2:
9664                // if Rd == �1111� && S == �1� then SEE CMP (register);
9665                // if Rn == �1101� then SEE SUB (SP minus register);
9666                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9667                d = Bits32 (opcode, 11, 8);
9668                n = Bits32 (opcode, 19, 16);
9669                m = Bits32 (opcode, 3, 0);
9670                setflags = BitIsSet (opcode, 20);
9671
9672                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9673                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9674
9675                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9676                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9677                    return false;
9678
9679                break;
9680
9681            case eEncodingA1:
9682                // if Rn == �1101� then SEE SUB (SP minus register);
9683                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9684                d = Bits32 (opcode, 15, 12);
9685                n = Bits32 (opcode, 19, 16);
9686                m = Bits32 (opcode, 3, 0);
9687                setflags = BitIsSet (opcode, 20);
9688
9689                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9690                if ((d == 15) && setflags)
9691                    EmulateSUBSPcLrEtc (opcode, encoding);
9692
9693                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9694                shift_n = DecodeImmShiftARM (opcode, shift_t);
9695
9696                break;
9697
9698            default:
9699                return false;
9700        }
9701
9702        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9703        uint32_t Rm = ReadCoreReg (m, &success);
9704        if (!success)
9705            return false;
9706
9707        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9708        if (!success)
9709            return false;
9710
9711        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9712        uint32_t Rn = ReadCoreReg (n, &success);
9713        if (!success)
9714            return false;
9715
9716        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9717
9718        // if d == 15 then // Can only occur for ARM encoding
9719            // ALUWritePC(result); // setflags is always FALSE here
9720        // else
9721            // R[d] = result;
9722            // if setflags then
9723                // APSR.N = result<31>;
9724                // APSR.Z = IsZeroBit(result);
9725                // APSR.C = carry;
9726                // APSR.V = overflow;
9727
9728        EmulateInstruction::Context context;
9729        context.type = eContextArithmetic;
9730        RegisterInfo reg_n;
9731        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9732        RegisterInfo reg_m;
9733        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9734        context.SetRegisterRegisterOperands (reg_n, reg_m);
9735
9736        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9737            return false;
9738    }
9739    return true;
9740}
9741
9742// A8.6.202 STREX
9743// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9744// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9745bool
9746EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9747{
9748#if 0
9749    if ConditionPassed() then
9750        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9751        address = R[n] + imm32;
9752        if ExclusiveMonitorsPass(address,4) then
9753            MemA[address,4] = R[t];
9754            R[d] = 0;
9755        else
9756            R[d] = 1;
9757#endif
9758
9759    bool success = false;
9760
9761    if (ConditionPassed(opcode))
9762    {
9763        uint32_t d;
9764        uint32_t t;
9765        uint32_t n;
9766        uint32_t imm32;
9767        const uint32_t addr_byte_size = GetAddressByteSize();
9768
9769        switch (encoding)
9770        {
9771            case eEncodingT1:
9772                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9773                d = Bits32 (opcode, 11, 8);
9774                t = Bits32 (opcode, 15, 12);
9775                n = Bits32 (opcode, 19, 16);
9776                imm32 = Bits32 (opcode, 7, 0) << 2;
9777
9778                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9779                if (BadReg (d) || BadReg (t) || (n == 15))
9780                  return false;
9781
9782                // if d == n || d == t then UNPREDICTABLE;
9783                if ((d == n) || (d == t))
9784                  return false;
9785
9786                break;
9787
9788            case eEncodingA1:
9789                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9790                d = Bits32 (opcode, 15, 12);
9791                t = Bits32 (opcode, 3, 0);
9792                n = Bits32 (opcode, 19, 16);
9793                imm32 = 0;
9794
9795                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9796                if ((d == 15) || (t == 15) || (n == 15))
9797                    return false;
9798
9799                // if d == n || d == t then UNPREDICTABLE;
9800                if ((d == n) || (d == t))
9801                    return false;
9802
9803                break;
9804
9805            default:
9806                return false;
9807        }
9808
9809        // address = R[n] + imm32;
9810        uint32_t Rn = ReadCoreReg (n, &success);
9811        if (!success)
9812            return false;
9813
9814        addr_t address = Rn + imm32;
9815
9816        RegisterInfo base_reg;
9817        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9818        RegisterInfo data_reg;
9819        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9820        EmulateInstruction::Context context;
9821        context.type = eContextRegisterStore;
9822        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9823
9824        // if ExclusiveMonitorsPass(address,4) then
9825        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9826        //                                                         always return true.
9827        if (true)
9828        {
9829            // MemA[address,4] = R[t];
9830            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9831            if (!success)
9832                return false;
9833
9834            if (!MemAWrite (context, address, Rt, addr_byte_size))
9835                return false;
9836
9837            // R[d] = 0;
9838            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9839                return false;
9840        }
9841        else
9842        {
9843            // R[d] = 1;
9844            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9845                return false;
9846        }
9847    }
9848    return true;
9849}
9850
9851// A8.6.197 STRB (immediate, ARM)
9852bool
9853EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9854{
9855#if 0
9856    if ConditionPassed() then
9857        EncodingSpecificOperations();
9858        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9859        address = if index then offset_addr else R[n];
9860        MemU[address,1] = R[t]<7:0>;
9861        if wback then R[n] = offset_addr;
9862#endif
9863
9864    bool success = false;
9865
9866    if (ConditionPassed(opcode))
9867    {
9868        uint32_t t;
9869        uint32_t n;
9870        uint32_t imm32;
9871        bool index;
9872        bool add;
9873        bool wback;
9874
9875        switch (encoding)
9876        {
9877            case eEncodingA1:
9878                // if P == �0� && W == �1� then SEE STRBT;
9879                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9880                t = Bits32 (opcode, 15, 12);
9881                n = Bits32 (opcode, 19, 16);
9882                imm32 = Bits32 (opcode, 11, 0);
9883
9884                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9885                index = BitIsSet (opcode, 24);
9886                add = BitIsSet (opcode, 23);
9887                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9888
9889                // if t == 15 then UNPREDICTABLE;
9890                if (t == 15)
9891                    return false;
9892
9893                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9894                if (wback && ((n == 15) || (n == t)))
9895                    return false;
9896
9897                break;
9898
9899            default:
9900                return false;
9901        }
9902
9903        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9904        uint32_t Rn = ReadCoreReg (n, &success);
9905        if (!success)
9906            return false;
9907
9908        addr_t offset_addr;
9909        if (add)
9910            offset_addr = Rn + imm32;
9911        else
9912            offset_addr = Rn - imm32;
9913
9914        // address = if index then offset_addr else R[n];
9915        addr_t address;
9916        if (index)
9917            address = offset_addr;
9918        else
9919            address = Rn;
9920
9921        // MemU[address,1] = R[t]<7:0>;
9922        uint32_t Rt = ReadCoreReg (t, &success);
9923        if (!success)
9924            return false;
9925
9926        RegisterInfo base_reg;
9927        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9928        RegisterInfo data_reg;
9929        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9930        EmulateInstruction::Context context;
9931        context.type = eContextRegisterStore;
9932        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9933
9934        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9935            return false;
9936
9937        // if wback then R[n] = offset_addr;
9938        if (wback)
9939        {
9940            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9941                return false;
9942        }
9943    }
9944    return true;
9945}
9946
9947// A8.6.194 STR (immediate, ARM)
9948bool
9949EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9950{
9951#if 0
9952    if ConditionPassed() then
9953        EncodingSpecificOperations();
9954        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9955        address = if index then offset_addr else R[n];
9956        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9957        if wback then R[n] = offset_addr;
9958#endif
9959
9960    bool success = false;
9961
9962    if (ConditionPassed(opcode))
9963    {
9964        uint32_t t;
9965        uint32_t n;
9966        uint32_t imm32;
9967        bool index;
9968        bool add;
9969        bool wback;
9970
9971        const uint32_t addr_byte_size = GetAddressByteSize();
9972
9973        switch (encoding)
9974        {
9975            case eEncodingA1:
9976                // if P == �0� && W == �1� then SEE STRT;
9977                // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9978                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9979                t = Bits32 (opcode, 15, 12);
9980                n = Bits32 (opcode, 19, 16);
9981                imm32 = Bits32 (opcode, 11, 0);
9982
9983                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9984                index = BitIsSet (opcode, 24);
9985                add = BitIsSet (opcode, 23);
9986                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9987
9988                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9989                if (wback && ((n == 15) || (n == t)))
9990                    return false;
9991
9992                break;
9993
9994            default:
9995                return false;
9996        }
9997
9998        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9999        uint32_t Rn = ReadCoreReg (n, &success);
10000        if (!success)
10001            return false;
10002
10003        addr_t offset_addr;
10004        if (add)
10005            offset_addr = Rn + imm32;
10006        else
10007            offset_addr = Rn - imm32;
10008
10009        // address = if index then offset_addr else R[n];
10010        addr_t address;
10011        if (index)
10012            address = offset_addr;
10013        else
10014            address = Rn;
10015
10016        RegisterInfo base_reg;
10017        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10018        RegisterInfo data_reg;
10019        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10020        EmulateInstruction::Context context;
10021        context.type = eContextRegisterStore;
10022        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10023
10024        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10025        uint32_t Rt = ReadCoreReg (t, &success);
10026        if (!success)
10027            return false;
10028
10029        if (t == 15)
10030        {
10031            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10032            if (!success)
10033                return false;
10034
10035            if (!MemUWrite (context, address, pc_value, addr_byte_size))
10036                return false;
10037        }
10038        else
10039        {
10040            if (!MemUWrite (context, address, Rt, addr_byte_size))
10041                  return false;
10042        }
10043
10044        // if wback then R[n] = offset_addr;
10045        if (wback)
10046        {
10047            context.type = eContextAdjustBaseRegister;
10048            context.SetImmediate (offset_addr);
10049
10050            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10051                return false;
10052        }
10053    }
10054    return true;
10055}
10056
10057// A8.6.66 LDRD (immediate)
10058// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10059// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10060bool
10061EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10062{
10063#if 0
10064    if ConditionPassed() then
10065        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10066        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10067        address = if index then offset_addr else R[n];
10068        R[t] = MemA[address,4];
10069        R[t2] = MemA[address+4,4];
10070        if wback then R[n] = offset_addr;
10071#endif
10072
10073    bool success = false;
10074
10075    if (ConditionPassed(opcode))
10076    {
10077        uint32_t t;
10078        uint32_t t2;
10079        uint32_t n;
10080        uint32_t imm32;
10081        bool index;
10082        bool add;
10083        bool wback;
10084
10085        switch (encoding)
10086        {
10087            case eEncodingT1:
10088                //if P == �0� && W == �0� then SEE �Related encodings�;
10089                //if Rn == �1111� then SEE LDRD (literal);
10090                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10091                t = Bits32 (opcode, 15, 12);
10092                t2 = Bits32 (opcode, 11, 8);
10093                n = Bits32 (opcode, 19, 16);
10094                imm32 = Bits32 (opcode, 7, 0) << 2;
10095
10096                //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10097                index = BitIsSet (opcode, 24);
10098                add = BitIsSet (opcode, 23);
10099                wback = BitIsSet (opcode, 21);
10100
10101                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10102                if (wback && ((n == t) || (n == t2)))
10103                    return false;
10104
10105                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10106                if (BadReg (t) || BadReg (t2) || (t == t2))
10107                    return false;
10108
10109                break;
10110
10111            case eEncodingA1:
10112                //if Rn == �1111� then SEE LDRD (literal);
10113                //if Rt<0> == �1� then UNPREDICTABLE;
10114                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10115                t = Bits32 (opcode, 15, 12);
10116                if (BitIsSet (t, 0))
10117                    return false;
10118                t2 = t + 1;
10119                n = Bits32 (opcode, 19, 16);
10120                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10121
10122                //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10123                index = BitIsSet (opcode, 24);
10124                add = BitIsSet (opcode, 23);
10125                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10126
10127                //if P == �0� && W == �1� then UNPREDICTABLE;
10128                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10129                    return false;
10130
10131                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10132                if (wback && ((n == t) || (n == t2)))
10133                    return false;
10134
10135                //if t2 == 15 then UNPREDICTABLE;
10136                if (t2 == 15)
10137                    return false;
10138
10139                break;
10140
10141            default:
10142                return false;
10143        }
10144
10145        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10146        uint32_t Rn = ReadCoreReg (n, &success);
10147        if (!success)
10148            return false;
10149
10150        addr_t offset_addr;
10151        if (add)
10152                  offset_addr = Rn + imm32;
10153        else
10154            offset_addr = Rn - imm32;
10155
10156        //address = if index then offset_addr else R[n];
10157        addr_t address;
10158        if (index)
10159            address = offset_addr;
10160        else
10161            address = Rn;
10162
10163        //R[t] = MemA[address,4];
10164        RegisterInfo base_reg;
10165        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10166
10167        EmulateInstruction::Context context;
10168        context.type = eContextRegisterLoad;
10169        context.SetRegisterPlusOffset (base_reg, address - Rn);
10170
10171        const uint32_t addr_byte_size = GetAddressByteSize();
10172        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10173        if (!success)
10174            return false;
10175
10176        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10177            return false;
10178
10179        //R[t2] = MemA[address+4,4];
10180
10181        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10182        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10183        if (!success)
10184            return false;
10185
10186        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10187            return false;
10188
10189        //if wback then R[n] = offset_addr;
10190        if (wback)
10191        {
10192            context.type = eContextAdjustBaseRegister;
10193            context.SetAddress (offset_addr);
10194
10195            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10196                return false;
10197        }
10198    }
10199    return true;
10200}
10201
10202// A8.6.68 LDRD (register)
10203// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10204// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10205bool
10206EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10207{
10208#if 0
10209    if ConditionPassed() then
10210        EncodingSpecificOperations();
10211        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10212        address = if index then offset_addr else R[n];
10213        R[t] = MemA[address,4];
10214        R[t2] = MemA[address+4,4];
10215        if wback then R[n] = offset_addr;
10216#endif
10217
10218    bool success = false;
10219
10220    if (ConditionPassed(opcode))
10221    {
10222        uint32_t t;
10223        uint32_t t2;
10224        uint32_t n;
10225        uint32_t m;
10226        bool index;
10227        bool add;
10228        bool wback;
10229
10230        switch (encoding)
10231        {
10232            case eEncodingA1:
10233                // if Rt<0> == �1� then UNPREDICTABLE;
10234                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10235                t = Bits32 (opcode, 15, 12);
10236                if (BitIsSet (t, 0))
10237                    return false;
10238                t2 = t + 1;
10239                n = Bits32 (opcode, 19, 16);
10240                m = Bits32 (opcode, 3, 0);
10241
10242                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10243                index = BitIsSet (opcode, 24);
10244                add = BitIsSet (opcode, 23);
10245                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10246
10247                // if P == �0� && W == �1� then UNPREDICTABLE;
10248                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10249                  return false;
10250
10251                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10252                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10253                  return false;
10254
10255                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10256                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10257                  return false;
10258
10259                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10260                if ((ArchVersion() < 6) && wback && (m == n))
10261                  return false;
10262                break;
10263
10264            default:
10265                return false;
10266        }
10267
10268        uint32_t Rn = ReadCoreReg (n, &success);
10269        if (!success)
10270            return false;
10271        RegisterInfo base_reg;
10272        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10273
10274        uint32_t Rm = ReadCoreReg (m, &success);
10275        if (!success)
10276            return false;
10277        RegisterInfo offset_reg;
10278        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10279
10280        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10281        addr_t offset_addr;
10282        if (add)
10283            offset_addr = Rn + Rm;
10284        else
10285            offset_addr = Rn - Rm;
10286
10287        // address = if index then offset_addr else R[n];
10288        addr_t address;
10289        if (index)
10290            address = offset_addr;
10291        else
10292            address = Rn;
10293
10294        EmulateInstruction::Context context;
10295        context.type = eContextRegisterLoad;
10296        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10297
10298        // R[t] = MemA[address,4];
10299        const uint32_t addr_byte_size = GetAddressByteSize();
10300        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10301        if (!success)
10302            return false;
10303
10304        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10305            return false;
10306
10307        // R[t2] = MemA[address+4,4];
10308
10309        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10310        if (!success)
10311            return false;
10312
10313        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10314            return false;
10315
10316        // if wback then R[n] = offset_addr;
10317        if (wback)
10318        {
10319            context.type = eContextAdjustBaseRegister;
10320            context.SetAddress (offset_addr);
10321
10322            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10323                return false;
10324        }
10325    }
10326    return true;
10327}
10328
10329// A8.6.200 STRD (immediate)
10330// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10331// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10332bool
10333EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10334{
10335#if 0
10336    if ConditionPassed() then
10337        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10338        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10339        address = if index then offset_addr else R[n];
10340        MemA[address,4] = R[t];
10341        MemA[address+4,4] = R[t2];
10342        if wback then R[n] = offset_addr;
10343#endif
10344
10345    bool success = false;
10346
10347    if (ConditionPassed(opcode))
10348    {
10349        uint32_t t;
10350        uint32_t t2;
10351        uint32_t n;
10352        uint32_t imm32;
10353        bool index;
10354        bool add;
10355        bool wback;
10356
10357        switch (encoding)
10358        {
10359            case eEncodingT1:
10360                // if P == �0� && W == �0� then SEE �Related encodings�;
10361                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10362                t = Bits32 (opcode, 15, 12);
10363                t2 = Bits32 (opcode, 11, 8);
10364                n = Bits32 (opcode, 19, 16);
10365                imm32 = Bits32 (opcode, 7, 0) << 2;
10366
10367                // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10368                index = BitIsSet (opcode, 24);
10369                add = BitIsSet (opcode, 23);
10370                wback = BitIsSet (opcode, 21);
10371
10372                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10373                if (wback && ((n == t) || (n == t2)))
10374                    return false;
10375
10376                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10377                if ((n == 15) || BadReg (t) || BadReg (t2))
10378                    return false;
10379
10380                break;
10381
10382            case eEncodingA1:
10383                // if Rt<0> == �1� then UNPREDICTABLE;
10384                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10385                t = Bits32 (opcode, 15, 12);
10386                if (BitIsSet (t, 0))
10387                    return false;
10388
10389                t2 = t + 1;
10390                n = Bits32 (opcode, 19, 16);
10391                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10392
10393                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10394                index = BitIsSet (opcode, 24);
10395                add = BitIsSet (opcode, 23);
10396                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10397
10398                // if P == �0� && W == �1� then UNPREDICTABLE;
10399                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10400                    return false;
10401
10402                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10403                if (wback && ((n == 15) || (n == t) || (n == t2)))
10404                    return false;
10405
10406                // if t2 == 15 then UNPREDICTABLE;
10407                if (t2 == 15)
10408                    return false;
10409
10410                break;
10411
10412            default:
10413                return false;
10414        }
10415
10416        RegisterInfo base_reg;
10417        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10418
10419        uint32_t Rn = ReadCoreReg (n, &success);
10420        if (!success)
10421            return false;
10422
10423        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10424        addr_t offset_addr;
10425        if (add)
10426            offset_addr = Rn + imm32;
10427        else
10428            offset_addr = Rn - imm32;
10429
10430        //address = if index then offset_addr else R[n];
10431        addr_t address;
10432        if (index)
10433            address = offset_addr;
10434        else
10435            address = Rn;
10436
10437        //MemA[address,4] = R[t];
10438        RegisterInfo data_reg;
10439        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10440
10441        uint32_t data = ReadCoreReg (t, &success);
10442        if (!success)
10443            return false;
10444
10445        EmulateInstruction::Context context;
10446        context.type = eContextRegisterStore;
10447        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10448
10449        const uint32_t addr_byte_size = GetAddressByteSize();
10450
10451        if (!MemAWrite (context, address, data, addr_byte_size))
10452            return false;
10453
10454        //MemA[address+4,4] = R[t2];
10455        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10456        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10457
10458        data = ReadCoreReg (t2, &success);
10459        if (!success)
10460            return false;
10461
10462        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10463            return false;
10464
10465        //if wback then R[n] = offset_addr;
10466        if (wback)
10467        {
10468            context.type = eContextAdjustBaseRegister;
10469            context.SetAddress (offset_addr);
10470
10471            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10472                return false;
10473        }
10474    }
10475    return true;
10476}
10477
10478
10479// A8.6.201 STRD (register)
10480bool
10481EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10482{
10483#if 0
10484    if ConditionPassed() then
10485        EncodingSpecificOperations();
10486        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10487        address = if index then offset_addr else R[n];
10488        MemA[address,4] = R[t];
10489        MemA[address+4,4] = R[t2];
10490        if wback then R[n] = offset_addr;
10491#endif
10492
10493    bool success = false;
10494
10495    if (ConditionPassed(opcode))
10496    {
10497        uint32_t t;
10498        uint32_t t2;
10499        uint32_t n;
10500        uint32_t m;
10501        bool index;
10502        bool add;
10503        bool wback;
10504
10505        switch (encoding)
10506        {
10507            case eEncodingA1:
10508                // if Rt<0> == �1� then UNPREDICTABLE;
10509                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10510                t = Bits32 (opcode, 15, 12);
10511                if (BitIsSet (t, 0))
10512                   return false;
10513
10514                t2 = t+1;
10515                n = Bits32 (opcode, 19, 16);
10516                m = Bits32 (opcode, 3, 0);
10517
10518                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10519                index = BitIsSet (opcode, 24);
10520                add = BitIsSet (opcode, 23);
10521                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10522
10523                // if P == �0� && W == �1� then UNPREDICTABLE;
10524                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10525                   return false;
10526
10527                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10528                if ((t2 == 15) || (m == 15))
10529                   return false;
10530
10531                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10532                if (wback && ((n == 15) || (n == t) || (n == t2)))
10533                   return false;
10534
10535                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10536                if ((ArchVersion() < 6) && wback && (m == n))
10537                   return false;
10538
10539                break;
10540
10541            default:
10542                return false;
10543        }
10544
10545        RegisterInfo base_reg;
10546        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10547        RegisterInfo offset_reg;
10548        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10549        RegisterInfo data_reg;
10550
10551        uint32_t Rn = ReadCoreReg (n, &success);
10552        if (!success)
10553            return false;
10554
10555        uint32_t Rm = ReadCoreReg (m, &success);
10556        if (!success)
10557            return false;
10558
10559        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10560        addr_t offset_addr;
10561        if (add)
10562            offset_addr = Rn + Rm;
10563        else
10564            offset_addr = Rn - Rm;
10565
10566        // address = if index then offset_addr else R[n];
10567        addr_t address;
10568        if (index)
10569            address = offset_addr;
10570        else
10571            address = Rn;
10572                          // MemA[address,4] = R[t];
10573        uint32_t Rt = ReadCoreReg (t, &success);
10574        if (!success)
10575            return false;
10576
10577        EmulateInstruction::Context context;
10578        context.type = eContextRegisterStore;
10579        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10580        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10581
10582        const uint32_t addr_byte_size = GetAddressByteSize();
10583
10584        if (!MemAWrite (context, address, Rt, addr_byte_size))
10585            return false;
10586
10587        // MemA[address+4,4] = R[t2];
10588        uint32_t Rt2 = ReadCoreReg (t2, &success);
10589        if (!success)
10590            return false;
10591
10592        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10593
10594        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10595
10596        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10597            return false;
10598
10599        // if wback then R[n] = offset_addr;
10600        if (wback)
10601        {
10602            context.type = eContextAdjustBaseRegister;
10603            context.SetAddress (offset_addr);
10604
10605            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10606                return false;
10607
10608        }
10609    }
10610    return true;
10611}
10612
10613// A8.6.319 VLDM
10614// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10615// an ARM core register.
10616bool
10617EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10618{
10619#if 0
10620    if ConditionPassed() then
10621        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10622        address = if add then R[n] else R[n]-imm32;
10623        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10624        for r = 0 to regs-1
10625            if single_regs then
10626                S[d+r] = MemA[address,4]; address = address+4;
10627            else
10628                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10629                // Combine the word-aligned words in the correct order for current endianness.
10630                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10631#endif
10632
10633    bool success = false;
10634
10635    if (ConditionPassed(opcode))
10636    {
10637        bool single_regs;
10638        bool add;
10639        bool wback;
10640        uint32_t d;
10641        uint32_t n;
10642        uint32_t imm32;
10643        uint32_t regs;
10644
10645        switch (encoding)
10646        {
10647            case eEncodingT1:
10648            case eEncodingA1:
10649                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10650                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10651                // if P == �1� && W == �0� then SEE VLDR;
10652                // if P == U && W == �1� then UNDEFINED;
10653                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10654                    return false;
10655
10656                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10657                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10658                single_regs = false;
10659                add = BitIsSet (opcode, 23);
10660                wback = BitIsSet (opcode, 21);
10661
10662                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10663                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10664                n = Bits32 (opcode, 19, 16);
10665                imm32 = Bits32 (opcode, 7, 0) << 2;
10666
10667                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10668                regs = Bits32 (opcode, 7, 0) / 2;
10669
10670                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10671                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10672                    return false;
10673
10674                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10675                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10676                    return false;
10677
10678                break;
10679
10680            case eEncodingT2:
10681            case eEncodingA2:
10682                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10683                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10684                // if P == �1� && W == �0� then SEE VLDR;
10685                // if P == U && W == �1� then UNDEFINED;
10686                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10687                    return false;
10688
10689                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10690                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10691                single_regs = true;
10692                add = BitIsSet (opcode, 23);
10693                wback = BitIsSet (opcode, 21);
10694                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10695                n = Bits32 (opcode, 19, 16);
10696
10697                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10698                imm32 = Bits32 (opcode, 7, 0) << 2;
10699                regs = Bits32 (opcode, 7, 0);
10700
10701                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10702                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10703                    return false;
10704
10705                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10706                if ((regs == 0) || ((d + regs) > 32))
10707                    return false;
10708                break;
10709
10710            default:
10711                return false;
10712        }
10713
10714        RegisterInfo base_reg;
10715        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10716
10717        uint32_t Rn = ReadCoreReg (n, &success);
10718        if (!success)
10719            return false;
10720
10721        // address = if add then R[n] else R[n]-imm32;
10722        addr_t address;
10723        if (add)
10724            address = Rn;
10725        else
10726            address = Rn - imm32;
10727
10728        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10729        EmulateInstruction::Context context;
10730
10731        if (wback)
10732        {
10733            uint32_t value;
10734            if (add)
10735                value = Rn + imm32;
10736            else
10737                value = Rn - imm32;
10738
10739            context.type = eContextAdjustBaseRegister;
10740            context.SetImmediateSigned (value - Rn);
10741            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10742                return false;
10743
10744        }
10745
10746        const uint32_t addr_byte_size = GetAddressByteSize();
10747        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10748
10749        context.type = eContextRegisterLoad;
10750
10751        // for r = 0 to regs-1
10752        for (uint32_t r = 0; r < regs; ++r)
10753        {
10754            if (single_regs)
10755            {
10756                // S[d+r] = MemA[address,4]; address = address+4;
10757                context.SetRegisterPlusOffset (base_reg, address - Rn);
10758
10759                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10760                if (!success)
10761                    return false;
10762
10763                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10764                    return false;
10765
10766                address = address + 4;
10767            }
10768            else
10769            {
10770                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10771                context.SetRegisterPlusOffset (base_reg, address - Rn);
10772                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10773                if (!success)
10774                    return false;
10775
10776                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10777                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10778                if (!success)
10779                    return false;
10780
10781                address = address + 8;
10782                // // Combine the word-aligned words in the correct order for current endianness.
10783                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10784                uint64_t data;
10785                if (GetByteOrder() == eByteOrderBig)
10786                {
10787                    data = word1;
10788                    data = (data << 32) | word2;
10789                }
10790                else
10791                {
10792                    data = word2;
10793                    data = (data << 32) | word1;
10794                }
10795
10796                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10797                    return false;
10798            }
10799        }
10800    }
10801    return true;
10802}
10803
10804// A8.6.399 VSTM
10805// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10806// ARM core register.
10807bool
10808EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10809{
10810#if 0
10811    if ConditionPassed() then
10812        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10813        address = if add then R[n] else R[n]-imm32;
10814        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10815        for r = 0 to regs-1
10816            if single_regs then
10817                MemA[address,4] = S[d+r]; address = address+4;
10818            else
10819                // Store as two word-aligned words in the correct order for current endianness.
10820                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10821                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10822                address = address+8;
10823#endif
10824
10825    bool success = false;
10826
10827    if (ConditionPassed (opcode))
10828    {
10829        bool single_regs;
10830        bool add;
10831        bool wback;
10832        uint32_t d;
10833        uint32_t n;
10834        uint32_t imm32;
10835        uint32_t regs;
10836
10837        switch (encoding)
10838        {
10839            case eEncodingT1:
10840            case eEncodingA1:
10841                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10842                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10843                // if P == �1� && W == �0� then SEE VSTR;
10844                // if P == U && W == �1� then UNDEFINED;
10845                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10846                    return false;
10847
10848                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10849                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10850                single_regs = false;
10851                add = BitIsSet (opcode, 23);
10852                wback = BitIsSet (opcode, 21);
10853
10854                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10855                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10856                n = Bits32 (opcode, 19, 16);
10857                imm32 = Bits32 (opcode, 7, 0) << 2;
10858
10859                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10860                regs = Bits32 (opcode, 7, 0) / 2;
10861
10862                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10863                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10864                    return false;
10865
10866                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10867                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10868                    return false;
10869
10870                break;
10871
10872            case eEncodingT2:
10873            case eEncodingA2:
10874                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10875                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10876                // if P == �1� && W == �0� then SEE VSTR;
10877                // if P == U && W == �1� then UNDEFINED;
10878                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10879                    return false;
10880
10881                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10882                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10883                single_regs = true;
10884                add = BitIsSet (opcode, 23);
10885                wback = BitIsSet (opcode, 21);
10886                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10887                n = Bits32 (opcode, 19, 16);
10888
10889                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10890                imm32 = Bits32 (opcode, 7, 0) << 2;
10891                regs = Bits32 (opcode, 7, 0);
10892
10893                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10894                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10895                    return false;
10896
10897                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10898                if ((regs == 0) || ((d + regs) > 32))
10899                    return false;
10900
10901                break;
10902
10903            default:
10904                return false;
10905        }
10906
10907        RegisterInfo base_reg;
10908        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10909
10910        uint32_t Rn = ReadCoreReg (n, &success);
10911        if (!success)
10912            return false;
10913
10914        // address = if add then R[n] else R[n]-imm32;
10915        addr_t address;
10916        if (add)
10917            address = Rn;
10918        else
10919            address = Rn - imm32;
10920
10921        EmulateInstruction::Context context;
10922        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10923        if (wback)
10924        {
10925            uint32_t value;
10926            if (add)
10927                value = Rn + imm32;
10928            else
10929                value = Rn - imm32;
10930
10931            context.type = eContextAdjustBaseRegister;
10932            context.SetRegisterPlusOffset (base_reg, value - Rn);
10933
10934            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10935                return false;
10936        }
10937
10938        const uint32_t addr_byte_size = GetAddressByteSize();
10939        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10940
10941        context.type = eContextRegisterStore;
10942        // for r = 0 to regs-1
10943        for (int r = 0; r < regs; ++r)
10944        {
10945
10946            if (single_regs)
10947            {
10948                // MemA[address,4] = S[d+r]; address = address+4;
10949                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10950                if (!success)
10951                    return false;
10952
10953                RegisterInfo data_reg;
10954                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10955                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10956                if (!MemAWrite (context, address, data, addr_byte_size))
10957                    return false;
10958
10959                address = address + 4;
10960            }
10961            else
10962            {
10963                // // Store as two word-aligned words in the correct order for current endianness.
10964                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10965                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10966                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10967                if (!success)
10968                    return false;
10969
10970                RegisterInfo data_reg;
10971                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10972
10973                if (GetByteOrder() == eByteOrderBig)
10974                {
10975                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10976                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10977                        return false;
10978
10979                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10980                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10981                        return false;
10982                }
10983                else
10984                {
10985                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10986                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10987                        return false;
10988
10989                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10990                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10991                        return false;
10992                }
10993                // address = address+8;
10994                address = address + 8;
10995            }
10996        }
10997    }
10998    return true;
10999}
11000
11001// A8.6.320
11002// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11003// an optional offset.
11004bool
11005EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11006{
11007#if 0
11008    if ConditionPassed() then
11009        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11010        base = if n == 15 then Align(PC,4) else R[n];
11011        address = if add then (base + imm32) else (base - imm32);
11012        if single_reg then
11013            S[d] = MemA[address,4];
11014        else
11015            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11016            // Combine the word-aligned words in the correct order for current endianness.
11017            D[d] = if BigEndian() then word1:word2 else word2:word1;
11018#endif
11019
11020    bool success = false;
11021
11022    if (ConditionPassed (opcode))
11023    {
11024        bool single_reg;
11025        bool add;
11026        uint32_t imm32;
11027        uint32_t d;
11028        uint32_t n;
11029
11030        switch (encoding)
11031        {
11032            case eEncodingT1:
11033            case eEncodingA1:
11034                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11035                single_reg = false;
11036                add = BitIsSet (opcode, 23);
11037                imm32 = Bits32 (opcode, 7, 0) << 2;
11038
11039                // d = UInt(D:Vd); n = UInt(Rn);
11040                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11041                n = Bits32 (opcode, 19, 16);
11042
11043                break;
11044
11045            case eEncodingT2:
11046            case eEncodingA2:
11047                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11048                single_reg = true;
11049                add = BitIsSet (opcode, 23);
11050                imm32 = Bits32 (opcode, 7, 0) << 2;
11051
11052                // d = UInt(Vd:D); n = UInt(Rn);
11053                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11054                n = Bits32 (opcode, 19, 16);
11055
11056                break;
11057
11058            default:
11059                return false;
11060        }
11061        RegisterInfo base_reg;
11062        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11063
11064        uint32_t Rn = ReadCoreReg (n, &success);
11065        if (!success)
11066            return false;
11067
11068        // base = if n == 15 then Align(PC,4) else R[n];
11069        uint32_t base;
11070        if (n == 15)
11071            base = AlignPC (Rn);
11072        else
11073            base = Rn;
11074
11075        // address = if add then (base + imm32) else (base - imm32);
11076        addr_t address;
11077        if (add)
11078            address = base + imm32;
11079        else
11080            address = base - imm32;
11081
11082        const uint32_t addr_byte_size = GetAddressByteSize();
11083        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11084
11085        EmulateInstruction::Context context;
11086        context.type = eContextRegisterLoad;
11087        context.SetRegisterPlusOffset (base_reg, address - base);
11088
11089        if (single_reg)
11090        {
11091            // S[d] = MemA[address,4];
11092            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11093            if (!success)
11094                return false;
11095
11096            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11097                return false;
11098        }
11099        else
11100        {
11101            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11102            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11103            if (!success)
11104                return false;
11105
11106            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11107            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11108            if (!success)
11109                return false;
11110            // // Combine the word-aligned words in the correct order for current endianness.
11111            // D[d] = if BigEndian() then word1:word2 else word2:word1;
11112            uint64_t data64;
11113            if (GetByteOrder() == eByteOrderBig)
11114            {
11115                data64 = word1;
11116                data64 = (data64 << 32) | word2;
11117            }
11118            else
11119            {
11120                data64 = word2;
11121                data64 = (data64 << 32) | word1;
11122            }
11123
11124            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11125                return false;
11126        }
11127    }
11128    return true;
11129}
11130
11131// A8.6.400 VSTR
11132// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11133// optional offset.
11134bool
11135EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11136{
11137#if 0
11138    if ConditionPassed() then
11139        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11140        address = if add then (R[n] + imm32) else (R[n] - imm32);
11141        if single_reg then
11142            MemA[address,4] = S[d];
11143        else
11144            // Store as two word-aligned words in the correct order for current endianness.
11145            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11146            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11147#endif
11148
11149    bool success = false;
11150
11151    if (ConditionPassed (opcode))
11152    {
11153        bool single_reg;
11154        bool add;
11155        uint32_t imm32;
11156        uint32_t d;
11157        uint32_t n;
11158
11159        switch (encoding)
11160        {
11161            case eEncodingT1:
11162            case eEncodingA1:
11163                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11164                single_reg = false;
11165                add = BitIsSet (opcode, 23);
11166                imm32 = Bits32 (opcode, 7, 0) << 2;
11167
11168                // d = UInt(D:Vd); n = UInt(Rn);
11169                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11170                n = Bits32 (opcode, 19, 16);
11171
11172                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11173                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11174                    return false;
11175
11176                break;
11177
11178            case eEncodingT2:
11179            case eEncodingA2:
11180                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11181                single_reg = true;
11182                add = BitIsSet (opcode, 23);
11183                imm32 = Bits32 (opcode, 7, 0) << 2;
11184
11185                // d = UInt(Vd:D); n = UInt(Rn);
11186                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11187                n = Bits32 (opcode, 19, 16);
11188
11189                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11190                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11191                    return false;
11192
11193                break;
11194
11195            default:
11196                return false;
11197        }
11198
11199        RegisterInfo base_reg;
11200        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11201
11202        uint32_t Rn = ReadCoreReg (n, &success);
11203        if (!success)
11204            return false;
11205
11206        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11207        addr_t address;
11208        if (add)
11209            address = Rn + imm32;
11210        else
11211            address = Rn - imm32;
11212
11213        const uint32_t addr_byte_size = GetAddressByteSize();
11214        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11215
11216        RegisterInfo data_reg;
11217        GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11218        EmulateInstruction::Context context;
11219        context.type = eContextRegisterStore;
11220        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11221
11222        if (single_reg)
11223        {
11224            // MemA[address,4] = S[d];
11225            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11226            if (!success)
11227                return false;
11228
11229            if (!MemAWrite (context, address, data, addr_byte_size))
11230                return false;
11231        }
11232        else
11233        {
11234            // // Store as two word-aligned words in the correct order for current endianness.
11235            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11236            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11237            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11238            if (!success)
11239                return false;
11240
11241            if (GetByteOrder() == eByteOrderBig)
11242            {
11243                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11244                    return false;
11245
11246                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11247                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11248                    return false;
11249            }
11250            else
11251            {
11252                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11253                    return false;
11254
11255                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11256                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11257                    return false;
11258            }
11259        }
11260    }
11261    return true;
11262}
11263
11264// A8.6.307 VLDI1 (multiple single elements)
11265// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11266// element of each register is loaded.
11267bool
11268EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11269{
11270#if 0
11271    if ConditionPassed() then
11272        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11273        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11274        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11275        for r = 0 to regs-1
11276            for e = 0 to elements-1
11277                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11278                address = address + ebytes;
11279#endif
11280
11281    bool success = false;
11282
11283    if (ConditionPassed (opcode))
11284    {
11285        uint32_t regs;
11286        uint32_t alignment;
11287        uint32_t ebytes;
11288        uint32_t esize;
11289        uint32_t elements;
11290        uint32_t d;
11291        uint32_t n;
11292        uint32_t m;
11293        bool wback;
11294        bool register_index;
11295
11296        switch (encoding)
11297        {
11298            case eEncodingT1:
11299            case eEncodingA1:
11300            {
11301                // case type of
11302                    // when �0111�
11303                        // regs = 1; if align<1> == �1� then UNDEFINED;
11304                    // when �1010�
11305                        // regs = 2; if align == �11� then UNDEFINED;
11306                    // when �0110�
11307                        // regs = 3; if align<1> == �1� then UNDEFINED;
11308                    // when �0010�
11309                        // regs = 4;
11310                    // otherwise
11311                        // SEE �Related encodings�;
11312                uint32_t type = Bits32 (opcode, 11, 8);
11313                uint32_t align = Bits32 (opcode, 5, 4);
11314                if (type == 7) // '0111'
11315                {
11316                    regs = 1;
11317                    if (BitIsSet (align, 1))
11318                        return false;
11319                }
11320                else if (type == 10) // '1010'
11321                {
11322                    regs = 2;
11323                    if (align == 3)
11324                        return false;
11325
11326                }
11327                else if (type == 6) // '0110'
11328                {
11329                    regs = 3;
11330                    if (BitIsSet (align, 1))
11331                        return false;
11332                }
11333                else if (type == 2) // '0010'
11334                {
11335                    regs = 4;
11336                }
11337                else
11338                    return false;
11339
11340                // alignment = if align == �00� then 1 else 4 << UInt(align);
11341                if (align == 0)
11342                    alignment = 1;
11343                else
11344                    alignment = 4 << align;
11345
11346                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11347                ebytes = 1 << Bits32 (opcode, 7, 6);
11348                esize = 8 * ebytes;
11349                elements = 8 / ebytes;
11350
11351                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11352                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11353                n = Bits32 (opcode, 19, 15);
11354                m = Bits32 (opcode, 3, 0);
11355
11356                // wback = (m != 15); register_index = (m != 15 && m != 13);
11357                wback = (m != 15);
11358                register_index = ((m != 15) && (m != 13));
11359
11360                // if d+regs > 32 then UNPREDICTABLE;
11361                if ((d + regs) > 32)
11362                    return false;
11363            }
11364                break;
11365
11366            default:
11367                return false;
11368        }
11369
11370        RegisterInfo base_reg;
11371        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11372
11373        uint32_t Rn = ReadCoreReg (n, &success);
11374        if (!success)
11375            return false;
11376
11377        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11378        addr_t address = Rn;
11379        if ((address % alignment) != 0)
11380            return false;
11381
11382        EmulateInstruction::Context context;
11383        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11384        if (wback)
11385        {
11386            uint32_t Rm = ReadCoreReg (m, &success);
11387            if (!success)
11388                return false;
11389
11390            uint32_t offset;
11391            if (register_index)
11392                offset = Rm;
11393            else
11394                offset = 8 * regs;
11395
11396            uint32_t value = Rn + offset;
11397            context.type = eContextAdjustBaseRegister;
11398            context.SetRegisterPlusOffset (base_reg, offset);
11399
11400            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11401                return false;
11402
11403        }
11404
11405        // for r = 0 to regs-1
11406        for (int r = 0; r < regs; ++r)
11407        {
11408            // for e = 0 to elements-1
11409            uint64_t assembled_data = 0;
11410            for (int e = 0; e < elements; ++e)
11411            {
11412                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11413                context.type = eContextRegisterLoad;
11414                context.SetRegisterPlusOffset (base_reg, address - Rn);
11415                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11416                if (!success)
11417                    return false;
11418
11419                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11420
11421                // address = address + ebytes;
11422                address = address + ebytes;
11423            }
11424            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11425                return false;
11426        }
11427    }
11428    return true;
11429}
11430
11431// A8.6.308 VLD1 (single element to one lane)
11432//
11433bool
11434EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11435{
11436#if 0
11437    if ConditionPassed() then
11438        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11439        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11440        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11441        Elem[D[d],index,esize] = MemU[address,ebytes];
11442#endif
11443
11444    bool success = false;
11445
11446    if (ConditionPassed (opcode))
11447    {
11448        uint32_t ebytes;
11449        uint32_t esize;
11450        uint32_t index;
11451        uint32_t alignment;
11452        uint32_t d;
11453        uint32_t n;
11454        uint32_t m;
11455        bool wback;
11456        bool register_index;
11457
11458        switch (encoding)
11459        {
11460            case eEncodingT1:
11461            case eEncodingA1:
11462            {
11463                uint32_t size = Bits32 (opcode, 11, 10);
11464                uint32_t index_align = Bits32 (opcode, 7, 4);
11465                // if size == �11� then SEE VLD1 (single element to all lanes);
11466                if (size == 3)
11467                   return EmulateVLD1SingleAll (opcode, encoding);
11468                // case size of
11469                if (size == 0) // when '00'
11470                {
11471                    // if index_align<0> != �0� then UNDEFINED;
11472                    if (BitIsClear (index_align, 0))
11473                        return false;
11474
11475                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11476                    ebytes = 1;
11477                    esize = 8;
11478                    index = Bits32 (index_align, 3, 1);
11479                    alignment = 1;
11480                }
11481                else if (size == 1) // when �01�
11482                {
11483                    // if index_align<1> != �0� then UNDEFINED;
11484                    if (BitIsClear (index_align, 1))
11485                        return false;
11486
11487                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11488                    ebytes = 2;
11489                    esize = 16;
11490                    index = Bits32 (index_align, 3, 2);
11491
11492                    // alignment = if index_align<0> == �0� then 1 else 2;
11493                    if (BitIsClear (index_align, 0))
11494                        alignment = 1;
11495                    else
11496                        alignment = 2;
11497                }
11498                else if (size == 2) // when �10�
11499                {
11500                    // if index_align<2> != �0� then UNDEFINED;
11501                    if (BitIsClear (index_align, 2))
11502                        return false;
11503
11504                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11505                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11506                        return false;
11507
11508                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11509                    ebytes = 4;
11510                    esize = 32;
11511                    index = Bit32 (index_align, 3);
11512
11513                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11514                    if (Bits32 (index_align, 1, 0) == 0)
11515                        alignment = 1;
11516                    else
11517                        alignment = 4;
11518                }
11519                else
11520                {
11521                    return false;
11522                }
11523                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11524                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11525                n = Bits32 (opcode, 19, 16);
11526                m = Bits32 (opcode, 3, 0);
11527
11528                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11529                wback = (m != 15);
11530                register_index = ((m != 15) && (m != 13));
11531
11532                if (n == 15)
11533                    return false;
11534
11535            }
11536                break;
11537
11538            default:
11539                return false;
11540        }
11541
11542        RegisterInfo base_reg;
11543        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11544
11545        uint32_t Rn = ReadCoreReg (n, &success);
11546        if (!success)
11547            return false;
11548
11549        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11550        addr_t address = Rn;
11551        if ((address % alignment) != 0)
11552            return false;
11553
11554        EmulateInstruction::Context context;
11555        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11556        if (wback)
11557        {
11558            uint32_t Rm = ReadCoreReg (m, &success);
11559            if (!success)
11560                return false;
11561
11562            uint32_t offset;
11563            if (register_index)
11564                offset = Rm;
11565            else
11566                offset = ebytes;
11567
11568            uint32_t value = Rn + offset;
11569
11570            context.type = eContextAdjustBaseRegister;
11571            context.SetRegisterPlusOffset (base_reg, offset);
11572
11573            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11574                return false;
11575        }
11576
11577        // Elem[D[d],index,esize] = MemU[address,ebytes];
11578        uint32_t element = MemURead (context, address, esize, 0, &success);
11579        if (!success)
11580            return false;
11581
11582        element = element << (index * esize);
11583
11584        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11585        if (!success)
11586            return false;
11587
11588        uint64_t all_ones = -1;
11589        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11590                                                          // at element & to the right of element.
11591        if (index > 0)
11592            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11593                                                                     // now mask should be 0's where element goes & 1's
11594                                                                     // everywhere else.
11595
11596        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11597        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11598
11599        context.type = eContextRegisterLoad;
11600        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11601            return false;
11602    }
11603    return true;
11604}
11605
11606// A8.6.391 VST1 (multiple single elements)
11607// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11608// interleaving.  Every element of each register is stored.
11609bool
11610EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11611{
11612#if 0
11613    if ConditionPassed() then
11614        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11615        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11616        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11617        for r = 0 to regs-1
11618            for e = 0 to elements-1
11619                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11620                address = address + ebytes;
11621#endif
11622
11623    bool success = false;
11624
11625    if (ConditionPassed (opcode))
11626    {
11627        uint32_t regs;
11628        uint32_t alignment;
11629        uint32_t ebytes;
11630        uint32_t esize;
11631        uint32_t elements;
11632        uint32_t d;
11633        uint32_t n;
11634        uint32_t m;
11635        bool wback;
11636        bool register_index;
11637
11638        switch (encoding)
11639        {
11640            case eEncodingT1:
11641            case eEncodingA1:
11642            {
11643                uint32_t type = Bits32 (opcode, 11, 8);
11644                uint32_t align = Bits32 (opcode, 5, 4);
11645
11646                // case type of
11647                if (type == 7)    // when �0111�
11648                {
11649                    // regs = 1; if align<1> == �1� then UNDEFINED;
11650                    regs = 1;
11651                    if (BitIsSet (align, 1))
11652                        return false;
11653                }
11654                else if (type == 10) // when �1010�
11655                {
11656                    // regs = 2; if align == �11� then UNDEFINED;
11657                    regs = 2;
11658                    if (align == 3)
11659                        return false;
11660                }
11661                else if (type == 6) // when �0110�
11662                {
11663                    // regs = 3; if align<1> == �1� then UNDEFINED;
11664                    regs = 3;
11665                    if (BitIsSet (align, 1))
11666                        return false;
11667                }
11668                else if (type == 2) // when �0010�
11669                    // regs = 4;
11670                    regs = 4;
11671                else // otherwise
11672                    // SEE �Related encodings�;
11673                    return false;
11674
11675                // alignment = if align == �00� then 1 else 4 << UInt(align);
11676                if (align == 0)
11677                    alignment = 1;
11678                else
11679                    alignment = 4 << align;
11680
11681                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11682                ebytes = 1 << Bits32 (opcode,7, 6);
11683                esize = 8 * ebytes;
11684                elements = 8 / ebytes;
11685
11686                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11687                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11688                n = Bits32 (opcode, 19, 16);
11689                m = Bits32 (opcode, 3, 0);
11690
11691                // wback = (m != 15); register_index = (m != 15 && m != 13);
11692                wback = (m != 15);
11693                register_index = ((m != 15) && (m != 13));
11694
11695                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11696                if ((d + regs) > 32)
11697                    return false;
11698
11699                if (n == 15)
11700                    return false;
11701
11702            }
11703                break;
11704
11705            default:
11706                return false;
11707        }
11708
11709        RegisterInfo base_reg;
11710        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11711
11712        uint32_t Rn = ReadCoreReg (n, &success);
11713        if (!success)
11714            return false;
11715
11716        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11717        addr_t address = Rn;
11718        if ((address % alignment) != 0)
11719            return false;
11720
11721        EmulateInstruction::Context context;
11722        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11723        if (wback)
11724        {
11725            uint32_t Rm = ReadCoreReg (m, &success);
11726            if (!success)
11727                return false;
11728
11729            uint32_t offset;
11730            if (register_index)
11731                offset = Rm;
11732            else
11733                offset = 8 * regs;
11734
11735            context.type = eContextAdjustBaseRegister;
11736            context.SetRegisterPlusOffset (base_reg, offset);
11737
11738            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11739                return false;
11740        }
11741
11742        RegisterInfo data_reg;
11743        context.type = eContextRegisterStore;
11744        // for r = 0 to regs-1
11745        for (int r = 0; r < regs; ++r)
11746        {
11747            GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11748            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11749            if (!success)
11750                return false;
11751
11752             // for e = 0 to elements-1
11753            for (int e = 0; e < elements; ++e)
11754            {
11755                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11756                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11757
11758                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11759                if (!MemUWrite (context, address, word, ebytes))
11760                    return false;
11761
11762                // address = address + ebytes;
11763                address = address + ebytes;
11764            }
11765        }
11766    }
11767    return true;
11768}
11769
11770// A8.6.392 VST1 (single element from one lane)
11771// This instruction stores one element to memory from one element of a register.
11772bool
11773EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11774{
11775#if 0
11776    if ConditionPassed() then
11777        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11778        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11779        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11780        MemU[address,ebytes] = Elem[D[d],index,esize];
11781#endif
11782
11783    bool success = false;
11784
11785    if (ConditionPassed (opcode))
11786    {
11787        uint32_t ebytes;
11788        uint32_t esize;
11789        uint32_t index;
11790        uint32_t alignment;
11791        uint32_t d;
11792        uint32_t n;
11793        uint32_t m;
11794        bool wback;
11795        bool register_index;
11796
11797        switch (encoding)
11798        {
11799            case eEncodingT1:
11800            case eEncodingA1:
11801            {
11802                uint32_t size = Bits32 (opcode, 11, 10);
11803                uint32_t index_align = Bits32 (opcode, 7, 4);
11804
11805                // if size == �11� then UNDEFINED;
11806                if (size == 3)
11807                    return false;
11808
11809                // case size of
11810                if (size == 0) // when �00�
11811                {
11812                    // if index_align<0> != �0� then UNDEFINED;
11813                    if (BitIsClear (index_align, 0))
11814                        return false;
11815                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11816                    ebytes = 1;
11817                    esize = 8;
11818                    index = Bits32 (index_align, 3, 1);
11819                    alignment = 1;
11820                }
11821                else if (size == 1) // when �01�
11822                {
11823                    // if index_align<1> != �0� then UNDEFINED;
11824                    if (BitIsClear (index_align, 1))
11825                        return false;
11826
11827                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11828                    ebytes = 2;
11829                    esize = 16;
11830                    index = Bits32 (index_align, 3, 2);
11831
11832                    // alignment = if index_align<0> == �0� then 1 else 2;
11833                    if (BitIsClear (index_align, 0))
11834                        alignment = 1;
11835                    else
11836                        alignment = 2;
11837                }
11838                else if (size == 2) // when �10�
11839                {
11840                    // if index_align<2> != �0� then UNDEFINED;
11841                    if (BitIsClear (index_align, 2))
11842                        return false;
11843
11844                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11845                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11846                        return false;
11847
11848                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11849                    ebytes = 4;
11850                    esize = 32;
11851                    index = Bit32 (index_align, 3);
11852
11853                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11854                    if (Bits32 (index_align, 1, 0) == 0)
11855                        alignment = 1;
11856                    else
11857                        alignment = 4;
11858                }
11859                else
11860                {
11861                    return false;
11862                }
11863                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11864                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11865                n = Bits32 (opcode, 19, 16);
11866                m = Bits32 (opcode, 3, 0);
11867
11868                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11869                wback = (m != 15);
11870                register_index = ((m != 15) && (m != 13));
11871
11872                if (n == 15)
11873                    return false;
11874            }
11875                break;
11876
11877            default:
11878                return false;
11879        }
11880
11881        RegisterInfo base_reg;
11882        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11883
11884        uint32_t Rn = ReadCoreReg (n, &success);
11885        if (!success)
11886            return false;
11887
11888        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11889        addr_t address = Rn;
11890        if ((address % alignment) != 0)
11891            return false;
11892
11893        EmulateInstruction::Context context;
11894        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11895        if (wback)
11896        {
11897            uint32_t Rm = ReadCoreReg (m, &success);
11898            if (!success)
11899                return false;
11900
11901            uint32_t offset;
11902            if (register_index)
11903                offset = Rm;
11904            else
11905                offset = ebytes;
11906
11907            context.type = eContextAdjustBaseRegister;
11908            context.SetRegisterPlusOffset (base_reg, offset);
11909
11910            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11911                return false;
11912        }
11913
11914        // MemU[address,ebytes] = Elem[D[d],index,esize];
11915        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11916        if (!success)
11917            return false;
11918
11919        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11920
11921        RegisterInfo data_reg;
11922        GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11923        context.type = eContextRegisterStore;
11924        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11925
11926        if (!MemUWrite (context, address, word, ebytes))
11927            return false;
11928    }
11929    return true;
11930}
11931
11932// A8.6.309 VLD1 (single element to all lanes)
11933// This instruction loads one element from memory into every element of one or two vectors.
11934bool
11935EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11936{
11937#if 0
11938    if ConditionPassed() then
11939        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11940        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11941        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11942        replicated_element = Replicate(MemU[address,ebytes], elements);
11943        for r = 0 to regs-1
11944            D[d+r] = replicated_element;
11945#endif
11946
11947    bool success = false;
11948
11949    if (ConditionPassed (opcode))
11950    {
11951        uint32_t ebytes;
11952        uint32_t elements;
11953        uint32_t regs;
11954        uint32_t alignment;
11955        uint32_t d;
11956        uint32_t n;
11957        uint32_t m;
11958        bool wback;
11959        bool register_index;
11960
11961        switch (encoding)
11962        {
11963            case eEncodingT1:
11964            case eEncodingA1:
11965            {
11966                //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11967                uint32_t size = Bits32 (opcode, 7, 6);
11968                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11969                    return false;
11970
11971                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11972                ebytes = 1 << size;
11973                elements = 8 / ebytes;
11974                if (BitIsClear (opcode, 5))
11975                    regs = 1;
11976                else
11977                    regs = 2;
11978
11979                //alignment = if a == �0� then 1 else ebytes;
11980                if (BitIsClear (opcode, 4))
11981                    alignment = 1;
11982                else
11983                    alignment = ebytes;
11984
11985                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11986                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11987                n = Bits32 (opcode, 19, 16);
11988                m = Bits32 (opcode, 3, 0);
11989
11990                //wback = (m != 15); register_index = (m != 15 && m != 13);
11991                wback = (m != 15);
11992                register_index = ((m != 15) && (m != 13));
11993
11994                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11995                if ((d + regs) > 32)
11996                    return false;
11997
11998                if (n == 15)
11999                    return false;
12000            }
12001            break;
12002
12003            default:
12004                return false;
12005        }
12006
12007        RegisterInfo base_reg;
12008        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12009
12010        uint32_t Rn = ReadCoreReg (n, &success);
12011        if (!success)
12012            return false;
12013
12014        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12015        addr_t address = Rn;
12016        if ((address % alignment) != 0)
12017            return false;
12018
12019        EmulateInstruction::Context context;
12020        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12021        if (wback)
12022        {
12023            uint32_t Rm = ReadCoreReg (m, &success);
12024            if (!success)
12025                return false;
12026
12027            uint32_t offset;
12028            if (register_index)
12029                offset = Rm;
12030            else
12031                offset = ebytes;
12032
12033            context.type = eContextAdjustBaseRegister;
12034            context.SetRegisterPlusOffset (base_reg, offset);
12035
12036            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12037                return false;
12038        }
12039
12040        // replicated_element = Replicate(MemU[address,ebytes], elements);
12041
12042        context.type = eContextRegisterLoad;
12043        uint64_t word = MemURead (context, address, ebytes, 0, &success);
12044        if (!success)
12045            return false;
12046
12047        uint64_t replicated_element = 0;
12048        uint32_t esize = ebytes * 8;
12049        for (int e = 0; e < elements; ++e)
12050            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12051
12052        // for r = 0 to regs-1
12053        for (int r = 0; r < regs; ++r)
12054        {
12055            // D[d+r] = replicated_element;
12056            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12057                return false;
12058        }
12059    }
12060    return true;
12061}
12062
12063// B6.2.13 SUBS PC, LR and related instructions
12064//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12065// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12066bool
12067EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12068{
12069#if 0
12070    if ConditionPassed() then
12071        EncodingSpecificOperations();
12072        if CurrentInstrSet() == InstrSet_ThumbEE then
12073            UNPREDICTABLE;
12074        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12075        case opcode of
12076            when �0000� result = R[n] AND operand2; // AND
12077            when �0001result = R[n] EOR operand2; // EOR
12078            when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12079            when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12080            when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12081            when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12082            when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12083            when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12084            when1100result = R[n] OR operand2; // ORR
12085            when1101result = operand2; // MOV
12086            when1110result = R[n] AND NOT(operand2); // BIC
12087            when1111result = NOT(operand2); // MVN
12088        CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12089        BranchWritePC(result);
12090#endif
12091
12092    bool success = false;
12093
12094    if (ConditionPassed (opcode))
12095    {
12096        uint32_t n;
12097        uint32_t m;
12098        uint32_t imm32;
12099        bool register_form;
12100        ARM_ShifterType shift_t;
12101        uint32_t shift_n;
12102        uint32_t code;
12103
12104        switch (encoding)
12105        {
12106            case eEncodingT1:
12107                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12108                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12109                n = 14;
12110                imm32 = Bits32 (opcode, 7, 0);
12111                register_form = false;
12112                code = 2;
12113
12114                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12115                if (InITBlock() && !LastInITBlock())
12116                    return false;
12117
12118                break;
12119
12120            case eEncodingA1:
12121                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12122                n = Bits32 (opcode, 19, 16);
12123                imm32 = ARMExpandImm (opcode);
12124                register_form = false;
12125                code = Bits32 (opcode, 24, 21);
12126
12127                break;
12128
12129            case eEncodingA2:
12130                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12131                n = Bits32 (opcode, 19, 16);
12132                m = Bits32 (opcode, 3, 0);
12133                register_form = true;
12134
12135                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12136                shift_n = DecodeImmShiftARM (opcode, shift_t);
12137
12138                break;
12139
12140            default:
12141                return false;
12142        }
12143
12144        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12145        uint32_t operand2;
12146        if (register_form)
12147        {
12148            uint32_t Rm = ReadCoreReg (m, &success);
12149            if (!success)
12150                return false;
12151
12152            operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12153            if (!success)
12154                return false;
12155        }
12156        else
12157        {
12158            operand2 = imm32;
12159        }
12160
12161        uint32_t Rn = ReadCoreReg (n, &success);
12162        if (!success)
12163            return false;
12164
12165        AddWithCarryResult result;
12166
12167        // case opcode of
12168        switch (code)
12169        {
12170            case 0: // when �0000�
12171                // result = R[n] AND operand2; // AND
12172                result.result = Rn & operand2;
12173                break;
12174
12175            case 1: // when �0001�
12176                // result = R[n] EOR operand2; // EOR
12177                result.result = Rn ^ operand2;
12178                break;
12179
12180            case 2: // when �0010�
12181                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12182                result = AddWithCarry (Rn, ~(operand2), 1);
12183                break;
12184
12185            case 3: // when �0011�
12186                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12187                result = AddWithCarry (~(Rn), operand2, 1);
12188                break;
12189
12190            case 4: // when �0100�
12191                // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12192                result = AddWithCarry (Rn, operand2, 0);
12193                break;
12194
12195            case 5: // when �0101�
12196                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12197                result = AddWithCarry (Rn, operand2, APSR_C);
12198                break;
12199
12200            case 6: // when �0110�
12201                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12202                result = AddWithCarry (Rn, ~(operand2), APSR_C);
12203                break;
12204
12205            case 7: // when �0111�
12206                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12207                result = AddWithCarry (~(Rn), operand2, APSR_C);
12208                break;
12209
12210            case 10: // when �1100�
12211                // result = R[n] OR operand2; // ORR
12212                result.result = Rn | operand2;
12213                break;
12214
12215            case 11: // when �1101�
12216                // result = operand2; // MOV
12217                result.result = operand2;
12218                break;
12219
12220            case 12: // when �1110�
12221                // result = R[n] AND NOT(operand2); // BIC
12222                result.result = Rn & ~(operand2);
12223                break;
12224
12225            case 15: // when �1111�
12226                // result = NOT(operand2); // MVN
12227                result.result = ~(operand2);
12228                break;
12229
12230            default:
12231                return false;
12232        }
12233        // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12234
12235        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12236        // the best.
12237        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12238        if (!success)
12239            return false;
12240
12241        CPSRWriteByInstr (spsr, 15, true);
12242
12243        // BranchWritePC(result);
12244        EmulateInstruction::Context context;
12245        context.type = eContextAdjustPC;
12246        context.SetImmediate (result.result);
12247
12248        BranchWritePC (context, result.result);
12249    }
12250    return true;
12251}
12252
12253EmulateInstructionARM::ARMOpcode*
12254EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12255{
12256    static ARMOpcode
12257    g_arm_opcodes[] =
12258    {
12259        //----------------------------------------------------------------------
12260        // Prologue instructions
12261        //----------------------------------------------------------------------
12262
12263        // push register(s)
12264        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12265        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12266
12267        // set r7 to point to a stack offset
12268        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12269        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12270        // copy the stack pointer to ip
12271        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12272        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12273        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12274
12275        // adjust the stack pointer
12276        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12277        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12278
12279        // push one register
12280        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12281        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12282
12283        // vector push consecutive extension register(s)
12284        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12285        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12286
12287        //----------------------------------------------------------------------
12288        // Epilogue instructions
12289        //----------------------------------------------------------------------
12290
12291        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12292        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12293        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12294        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12295
12296        //----------------------------------------------------------------------
12297        // Supervisor Call (previously Software Interrupt)
12298        //----------------------------------------------------------------------
12299        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12300
12301        //----------------------------------------------------------------------
12302        // Branch instructions
12303        //----------------------------------------------------------------------
12304        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12305        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12306        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12307        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12308        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12309        // for example, "bx lr"
12310        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12311        // bxj
12312        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12313
12314        //----------------------------------------------------------------------
12315        // Data-processing instructions
12316        //----------------------------------------------------------------------
12317        // adc (immediate)
12318        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12319        // adc (register)
12320        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12321        // add (immediate)
12322        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12323        // add (register)
12324        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12325        // add (register-shifted register)
12326        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12327        // adr
12328        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12329        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12330        // and (immediate)
12331        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12332        // and (register)
12333        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12334        // bic (immediate)
12335        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12336        // bic (register)
12337        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12338        // eor (immediate)
12339        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12340        // eor (register)
12341        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12342        // orr (immediate)
12343        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12344        // orr (register)
12345        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12346        // rsb (immediate)
12347        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12348        // rsb (register)
12349        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12350        // rsc (immediate)
12351        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12352        // rsc (register)
12353        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12354        // sbc (immediate)
12355        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12356        // sbc (register)
12357        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12358        // sub (immediate, ARM)
12359        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12360        // sub (sp minus immediate)
12361        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12362        // sub (register)
12363        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12364        // teq (immediate)
12365        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12366        // teq (register)
12367        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12368        // tst (immediate)
12369        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12370        // tst (register)
12371        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12372
12373        // mov (immediate)
12374        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12375        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12376        // mov (register)
12377        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12378        // mvn (immediate)
12379        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12380        // mvn (register)
12381        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12382        // cmn (immediate)
12383        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12384        // cmn (register)
12385        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12386        // cmp (immediate)
12387        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12388        // cmp (register)
12389        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12390        // asr (immediate)
12391        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12392        // asr (register)
12393        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12394        // lsl (immediate)
12395        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12396        // lsl (register)
12397        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12398        // lsr (immediate)
12399        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12400        // lsr (register)
12401        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12402        // rrx is a special case encoding of ror (immediate)
12403        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12404        // ror (immediate)
12405        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12406        // ror (register)
12407        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12408        // mul
12409        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12410
12411        // subs pc, lr and related instructions
12412        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12413        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12414
12415        //----------------------------------------------------------------------
12416        // Load instructions
12417        //----------------------------------------------------------------------
12418        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12419        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12420        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12421        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12422        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12423        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12424        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12425        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12426        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12427        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12428        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12429        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12430        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12431        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12432        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12433        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12434        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12435        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12436        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12437        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12438        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12439        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12440        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12441        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12442        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12443
12444        //----------------------------------------------------------------------
12445        // Store instructions
12446        //----------------------------------------------------------------------
12447        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12448        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12449        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12450        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12451        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12452        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12453        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12454        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12455        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12456        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12457        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12458        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12459        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12460        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12461        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12462        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12463        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12464
12465        //----------------------------------------------------------------------
12466        // Other instructions
12467        //----------------------------------------------------------------------
12468        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12469        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12470        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12471        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12472        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12473
12474    };
12475    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12476
12477    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12478    {
12479        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12480            (g_arm_opcodes[i].variants & arm_isa) != 0)
12481            return &g_arm_opcodes[i];
12482    }
12483    return NULL;
12484}
12485
12486
12487EmulateInstructionARM::ARMOpcode*
12488EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12489{
12490
12491    static ARMOpcode
12492    g_thumb_opcodes[] =
12493    {
12494        //----------------------------------------------------------------------
12495        // Prologue instructions
12496        //----------------------------------------------------------------------
12497
12498        // push register(s)
12499        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12500        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12501        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12502
12503        // set r7 to point to a stack offset
12504        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12505        // copy the stack pointer to r7
12506        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12507        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12508        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12509
12510        // PC-relative load into register (see also EmulateADDSPRm)
12511        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12512
12513        // adjust the stack pointer
12514        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12515        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12516        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12517        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12518        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12519
12520        // vector push consecutive extension register(s)
12521        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12522        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12523
12524        //----------------------------------------------------------------------
12525        // Epilogue instructions
12526        //----------------------------------------------------------------------
12527
12528        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12529        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12530        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12531        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12532        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12533        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12534        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12535
12536        //----------------------------------------------------------------------
12537        // Supervisor Call (previously Software Interrupt)
12538        //----------------------------------------------------------------------
12539        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12540
12541        //----------------------------------------------------------------------
12542        // If Then makes up to four following instructions conditional.
12543        //----------------------------------------------------------------------
12544        // The next 5 opcode _must_ come before the if then instruction
12545        { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12546        { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12547        { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12548        { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12549        { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12550        { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12551
12552        //----------------------------------------------------------------------
12553        // Branch instructions
12554        //----------------------------------------------------------------------
12555        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12556        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12557        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12558        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12559        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12560        // J1 == J2 == 1
12561        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12562        // J1 == J2 == 1
12563        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12564        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12565        // for example, "bx lr"
12566        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12567        // bxj
12568        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12569        // compare and branch
12570        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12571        // table branch byte
12572        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12573        // table branch halfword
12574        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12575
12576        //----------------------------------------------------------------------
12577        // Data-processing instructions
12578        //----------------------------------------------------------------------
12579        // adc (immediate)
12580        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12581        // adc (register)
12582        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12583        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12584        // add (register)
12585        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12586        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12587        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12588        // adr
12589        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12590        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12591        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12592        // and (immediate)
12593        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12594        // and (register)
12595        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12596        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12597        // bic (immediate)
12598        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12599        // bic (register)
12600        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12601        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12602        // eor (immediate)
12603        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12604        // eor (register)
12605        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12606        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12607        // orr (immediate)
12608        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12609        // orr (register)
12610        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12611        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12612        // rsb (immediate)
12613        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12614        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12615        // rsb (register)
12616        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12617        // sbc (immediate)
12618        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12619        // sbc (register)
12620        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12621        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12622        // add (immediate, Thumb)
12623        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12624        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12625        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12626        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12627        // sub (immediate, Thumb)
12628        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12629        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12630        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12631        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12632        // sub (sp minus immediate)
12633        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12634        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12635        // sub (register)
12636        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12637        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12638        // teq (immediate)
12639        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12640        // teq (register)
12641        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12642        // tst (immediate)
12643        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12644        // tst (register)
12645        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12646        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12647
12648
12649        // move from high register to high register
12650        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12651        // move from low register to low register
12652        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12653        // mov{s}<c>.w <Rd>, <Rm>
12654        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12655        // move immediate
12656        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12657        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12658        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12659        // mvn (immediate)
12660        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12661        // mvn (register)
12662        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12663        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12664        // cmn (immediate)
12665        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12666        // cmn (register)
12667        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12668        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12669        // cmp (immediate)
12670        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12671        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12672        // cmp (register) (Rn and Rm both from r0-r7)
12673        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12674        // cmp (register) (Rn and Rm not both from r0-r7)
12675        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12676        // asr (immediate)
12677        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12678        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12679        // asr (register)
12680        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12681        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12682        // lsl (immediate)
12683        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12684        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12685        // lsl (register)
12686        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12687        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12688        // lsr (immediate)
12689        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12690        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12691        // lsr (register)
12692        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12693        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12694        // rrx is a special case encoding of ror (immediate)
12695        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12696        // ror (immediate)
12697        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12698        // ror (register)
12699        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12700        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12701        // mul
12702        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12703        // mul
12704        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12705
12706        // subs pc, lr and related instructions
12707        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12708
12709        //----------------------------------------------------------------------
12710        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12711        // otherwise the wrong instructions will be selected.
12712        //----------------------------------------------------------------------
12713
12714        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12715        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12716
12717        //----------------------------------------------------------------------
12718        // Load instructions
12719        //----------------------------------------------------------------------
12720        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12721        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12722        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12723        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12724        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12725        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12726        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12727                  // Thumb2 PC-relative load into register
12728        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12729        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12730        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12731        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12732        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12733        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12734        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12735        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12736        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12737        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12738        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12739        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12740        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12741        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12742        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12743        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12744        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12745        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12746        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12747        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12748        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12749        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12750        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12751        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12752        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12753        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12754        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12755        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12756        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12757        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12758        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12759        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12760        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12761
12762        //----------------------------------------------------------------------
12763        // Store instructions
12764        //----------------------------------------------------------------------
12765        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12766        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12767        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12768        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12769        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12770        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12771        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12772        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12773        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12774        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12775        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12776        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12777        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12778        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12779        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12780        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12781        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12782        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12783        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12784        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12785        { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12786        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12787
12788        //----------------------------------------------------------------------
12789        // Other instructions
12790        //----------------------------------------------------------------------
12791        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12792        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12793        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12794        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12795        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12796        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12797        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12798        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12799    };
12800
12801    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12802    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12803    {
12804        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12805            (g_thumb_opcodes[i].variants & arm_isa) != 0)
12806            return &g_thumb_opcodes[i];
12807    }
12808    return NULL;
12809}
12810
12811bool
12812EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12813{
12814    m_arch = arch;
12815    m_arm_isa = 0;
12816    const char *arch_cstr = arch.GetArchitectureName ();
12817    if (arch_cstr)
12818    {
12819        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12820        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12821        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12822        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12823        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12824        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12825        else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12826        else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12827        else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12828        else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12829        else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12830        else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12831        else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12832    }
12833    return m_arm_isa != 0;
12834}
12835
12836bool
12837EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12838{
12839    if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12840    {
12841        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12842            m_opcode_mode = eModeThumb;
12843        else
12844        {
12845            AddressClass addr_class = inst_addr.GetAddressClass();
12846
12847            if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12848                m_opcode_mode = eModeARM;
12849            else if (addr_class == eAddressClassCodeAlternateISA)
12850                m_opcode_mode = eModeThumb;
12851            else
12852                return false;
12853        }
12854        if (m_opcode_mode == eModeThumb)
12855            m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12856        else
12857            m_opcode_cpsr = CPSR_MODE_USR;
12858        return true;
12859    }
12860    return false;
12861}
12862
12863bool
12864EmulateInstructionARM::ReadInstruction ()
12865{
12866    bool success = false;
12867    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12868    if (success)
12869    {
12870        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12871        if (success)
12872        {
12873            Context read_inst_context;
12874            read_inst_context.type = eContextReadOpcode;
12875            read_inst_context.SetNoArgs ();
12876
12877            if (m_opcode_cpsr & MASK_CPSR_T)
12878            {
12879                m_opcode_mode = eModeThumb;
12880                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12881
12882                if (success)
12883                {
12884                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12885                    {
12886                        m_opcode.SetOpcode16 (thumb_opcode);
12887                    }
12888                    else
12889                    {
12890                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12891                    }
12892                }
12893            }
12894            else
12895            {
12896                m_opcode_mode = eModeARM;
12897                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12898            }
12899        }
12900    }
12901    if (!success)
12902    {
12903        m_opcode_mode = eModeInvalid;
12904        m_addr = LLDB_INVALID_ADDRESS;
12905    }
12906    return success;
12907}
12908
12909uint32_t
12910EmulateInstructionARM::ArchVersion ()
12911{
12912    return m_arm_isa;
12913}
12914
12915bool
12916EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12917{
12918   // If we are ignoring conditions, then always return true.
12919   // this allows us to iterate over disassembly code and still
12920   // emulate an instruction even if we don't have all the right
12921   // bits set in the CPSR register...
12922    if (m_ignore_conditions)
12923        return true;
12924
12925    if (is_conditional)
12926        *is_conditional = true;
12927
12928    const uint32_t cond = CurrentCond (opcode);
12929
12930    if (cond == UINT32_MAX)
12931        return false;
12932
12933    bool result = false;
12934    switch (UnsignedBits(cond, 3, 1))
12935    {
12936    case 0:
12937		if (m_opcode_cpsr == 0)
12938			result = true;
12939        else
12940            result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12941		break;
12942    case 1:
12943        if (m_opcode_cpsr == 0)
12944            result = true;
12945        else
12946            result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12947		break;
12948    case 2:
12949        if (m_opcode_cpsr == 0)
12950            result = true;
12951        else
12952            result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12953		break;
12954    case 3:
12955        if (m_opcode_cpsr == 0)
12956            result = true;
12957        else
12958            result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12959		break;
12960    case 4:
12961        if (m_opcode_cpsr == 0)
12962            result = true;
12963        else
12964            result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12965		break;
12966    case 5:
12967        if (m_opcode_cpsr == 0)
12968            result = true;
12969        else
12970		{
12971            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12972            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12973            result = n == v;
12974        }
12975        break;
12976    case 6:
12977        if (m_opcode_cpsr == 0)
12978            result = true;
12979        else
12980		{
12981            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12982            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12983            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12984        }
12985        break;
12986    case 7:
12987        // Always execute (cond == 0b1110, or the special 0b1111 which gives
12988        // opcodes different meanings, but always means execution happpens.
12989        if (is_conditional)
12990            *is_conditional = false;
12991        result = true;
12992        break;
12993    }
12994
12995    if (cond & 1)
12996        result = !result;
12997    return result;
12998}
12999
13000uint32_t
13001EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13002{
13003    switch (m_opcode_mode)
13004    {
13005    case eModeInvalid:
13006        break;
13007
13008    case eModeARM:
13009        return UnsignedBits(opcode, 31, 28);
13010
13011    case eModeThumb:
13012        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13013        // 'cond' field of the encoding.
13014        {
13015            const uint32_t byte_size = m_opcode.GetByteSize();
13016            if (byte_size == 2)
13017            {
13018                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13019                    return Bits32(opcode, 11, 7);
13020            }
13021            else if (byte_size == 4)
13022            {
13023                if (Bits32(opcode, 31, 27) == 0x1e &&
13024                    Bits32(opcode, 15, 14) == 0x02 &&
13025                    Bits32(opcode, 12, 12) == 0x00 &&
13026                    Bits32(opcode, 25, 22) <= 0x0d)
13027                {
13028                    return Bits32(opcode, 25, 22);
13029                }
13030            }
13031            else
13032                // We have an invalid thumb instruction, let's bail out.
13033                break;
13034
13035            return m_it_session.GetCond();
13036        }
13037    }
13038    return UINT32_MAX;  // Return invalid value
13039}
13040
13041bool
13042EmulateInstructionARM::InITBlock()
13043{
13044    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13045}
13046
13047bool
13048EmulateInstructionARM::LastInITBlock()
13049{
13050    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13051}
13052
13053bool
13054EmulateInstructionARM::BadMode (uint32_t mode)
13055{
13056
13057    switch (mode)
13058    {
13059        case 16: return false; // '10000'
13060        case 17: return false; // '10001'
13061        case 18: return false; // '10010'
13062        case 19: return false; // '10011'
13063        case 22: return false; // '10110'
13064        case 23: return false; // '10111'
13065        case 27: return false; // '11011'
13066        case 31: return false; // '11111'
13067        default: return true;
13068    }
13069    return true;
13070}
13071
13072bool
13073EmulateInstructionARM::CurrentModeIsPrivileged ()
13074{
13075    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13076
13077    if (BadMode (mode))
13078        return false;
13079
13080    if (mode == 16)
13081        return false;
13082
13083    return true;
13084}
13085
13086void
13087EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13088{
13089    bool privileged = CurrentModeIsPrivileged();
13090
13091    uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13092
13093    if (BitIsSet (bytemask, 3))
13094    {
13095        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13096        if (affect_execstate)
13097            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13098    }
13099
13100    if (BitIsSet (bytemask, 2))
13101    {
13102        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13103    }
13104
13105    if (BitIsSet (bytemask, 1))
13106    {
13107        if (affect_execstate)
13108            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13109        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13110        if (privileged)
13111            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13112    }
13113
13114    if (BitIsSet (bytemask, 0))
13115    {
13116        if (privileged)
13117            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13118        if (affect_execstate)
13119            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13120        if (privileged)
13121            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13122    }
13123
13124    m_opcode_cpsr = tmp_cpsr;
13125}
13126
13127
13128bool
13129EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13130{
13131    addr_t target;
13132
13133    // Check the current instruction set.
13134    if (CurrentInstrSet() == eModeARM)
13135        target = addr & 0xfffffffc;
13136    else
13137        target = addr & 0xfffffffe;
13138
13139    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13140        return false;
13141
13142    return true;
13143}
13144
13145// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13146bool
13147EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13148{
13149    addr_t target;
13150    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13151    // we want to record it and issue a WriteRegister callback so the clients
13152    // can track the mode changes accordingly.
13153    bool cpsr_changed = false;
13154
13155    if (BitIsSet(addr, 0))
13156    {
13157        if (CurrentInstrSet() != eModeThumb)
13158        {
13159            SelectInstrSet(eModeThumb);
13160            cpsr_changed = true;
13161        }
13162        target = addr & 0xfffffffe;
13163        context.SetISA (eModeThumb);
13164    }
13165    else if (BitIsClear(addr, 1))
13166    {
13167        if (CurrentInstrSet() != eModeARM)
13168        {
13169            SelectInstrSet(eModeARM);
13170            cpsr_changed = true;
13171        }
13172        target = addr & 0xfffffffc;
13173        context.SetISA (eModeARM);
13174    }
13175    else
13176        return false; // address<1:0> == '10' => UNPREDICTABLE
13177
13178    if (cpsr_changed)
13179    {
13180        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13181            return false;
13182    }
13183    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13184        return false;
13185
13186    return true;
13187}
13188
13189// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13190bool
13191EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13192{
13193    if (ArchVersion() >= ARMv5T)
13194        return BXWritePC(context, addr);
13195    else
13196        return BranchWritePC((const Context)context, addr);
13197}
13198
13199// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13200bool
13201EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13202{
13203    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13204        return BXWritePC(context, addr);
13205    else
13206        return BranchWritePC((const Context)context, addr);
13207}
13208
13209EmulateInstructionARM::Mode
13210EmulateInstructionARM::CurrentInstrSet ()
13211{
13212    return m_opcode_mode;
13213}
13214
13215// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13216// ReadInstruction() is performed.  This function has a side effect of updating
13217// the m_new_inst_cpsr member variable if necessary.
13218bool
13219EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13220{
13221    m_new_inst_cpsr = m_opcode_cpsr;
13222    switch (arm_or_thumb)
13223    {
13224    default:
13225        return false;
13226    case eModeARM:
13227        // Clear the T bit.
13228        m_new_inst_cpsr &= ~MASK_CPSR_T;
13229        break;
13230    case eModeThumb:
13231        // Set the T bit.
13232        m_new_inst_cpsr |= MASK_CPSR_T;
13233        break;
13234    }
13235    return true;
13236}
13237
13238// This function returns TRUE if the processor currently provides support for
13239// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13240// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13241bool
13242EmulateInstructionARM::UnalignedSupport()
13243{
13244    return (ArchVersion() >= ARMv7);
13245}
13246
13247// The main addition and subtraction instructions can produce status information
13248// about both unsigned carry and signed overflow conditions.  This status
13249// information can be used to synthesize multi-word additions and subtractions.
13250EmulateInstructionARM::AddWithCarryResult
13251EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13252{
13253    uint32_t result;
13254    uint8_t carry_out;
13255    uint8_t overflow;
13256
13257    uint64_t unsigned_sum = x + y + carry_in;
13258    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13259
13260    result = UnsignedBits(unsigned_sum, 31, 0);
13261//    carry_out = (result == unsigned_sum ? 0 : 1);
13262    overflow = ((int32_t)result == signed_sum ? 0 : 1);
13263
13264    if (carry_in)
13265        carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13266    else
13267        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13268
13269    AddWithCarryResult res = { result, carry_out, overflow };
13270    return res;
13271}
13272
13273uint32_t
13274EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13275{
13276    uint32_t reg_kind, reg_num;
13277    switch (num)
13278    {
13279    case SP_REG:
13280        reg_kind = eRegisterKindGeneric;
13281        reg_num  = LLDB_REGNUM_GENERIC_SP;
13282        break;
13283    case LR_REG:
13284        reg_kind = eRegisterKindGeneric;
13285        reg_num  = LLDB_REGNUM_GENERIC_RA;
13286        break;
13287    case PC_REG:
13288        reg_kind = eRegisterKindGeneric;
13289        reg_num  = LLDB_REGNUM_GENERIC_PC;
13290        break;
13291    default:
13292        if (num < SP_REG)
13293        {
13294            reg_kind = eRegisterKindDWARF;
13295            reg_num  = dwarf_r0 + num;
13296        }
13297        else
13298        {
13299            //assert(0 && "Invalid register number");
13300            *success = false;
13301            return UINT32_MAX;
13302        }
13303        break;
13304    }
13305
13306    // Read our register.
13307    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13308
13309    // When executing an ARM instruction , PC reads as the address of the current
13310    // instruction plus 8.
13311    // When executing a Thumb instruction , PC reads as the address of the current
13312    // instruction plus 4.
13313    if (num == 15)
13314    {
13315        if (CurrentInstrSet() == eModeARM)
13316            val += 8;
13317        else
13318            val += 4;
13319    }
13320
13321    return val;
13322}
13323
13324// Write the result to the ARM core register Rd, and optionally update the
13325// condition flags based on the result.
13326//
13327// This helper method tries to encapsulate the following pseudocode from the
13328// ARM Architecture Reference Manual:
13329//
13330// if d == 15 then         // Can only occur for encoding A1
13331//     ALUWritePC(result); // setflags is always FALSE here
13332// else
13333//     R[d] = result;
13334//     if setflags then
13335//         APSR.N = result<31>;
13336//         APSR.Z = IsZeroBit(result);
13337//         APSR.C = carry;
13338//         // APSR.V unchanged
13339//
13340// In the above case, the API client does not pass in the overflow arg, which
13341// defaults to ~0u.
13342bool
13343EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13344                                                  const uint32_t result,
13345                                                  const uint32_t Rd,
13346                                                  bool setflags,
13347                                                  const uint32_t carry,
13348                                                  const uint32_t overflow)
13349{
13350    if (Rd == 15)
13351    {
13352        if (!ALUWritePC (context, result))
13353            return false;
13354    }
13355    else
13356    {
13357        uint32_t reg_kind, reg_num;
13358        switch (Rd)
13359        {
13360        case SP_REG:
13361            reg_kind = eRegisterKindGeneric;
13362            reg_num  = LLDB_REGNUM_GENERIC_SP;
13363            break;
13364        case LR_REG:
13365            reg_kind = eRegisterKindGeneric;
13366            reg_num  = LLDB_REGNUM_GENERIC_RA;
13367            break;
13368        default:
13369            reg_kind = eRegisterKindDWARF;
13370            reg_num  = dwarf_r0 + Rd;
13371        }
13372        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13373            return false;
13374        if (setflags)
13375            return WriteFlags (context, result, carry, overflow);
13376    }
13377    return true;
13378}
13379
13380// This helper method tries to encapsulate the following pseudocode from the
13381// ARM Architecture Reference Manual:
13382//
13383// APSR.N = result<31>;
13384// APSR.Z = IsZeroBit(result);
13385// APSR.C = carry;
13386// APSR.V = overflow
13387//
13388// Default arguments can be specified for carry and overflow parameters, which means
13389// not to update the respective flags.
13390bool
13391EmulateInstructionARM::WriteFlags (Context &context,
13392                                   const uint32_t result,
13393                                   const uint32_t carry,
13394                                   const uint32_t overflow)
13395{
13396    m_new_inst_cpsr = m_opcode_cpsr;
13397    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13398    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13399    if (carry != ~0u)
13400        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13401    if (overflow != ~0u)
13402        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13403    if (m_new_inst_cpsr != m_opcode_cpsr)
13404    {
13405        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13406            return false;
13407    }
13408    return true;
13409}
13410
13411bool
13412EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13413{
13414    // Advance the ITSTATE bits to their values for the next instruction.
13415    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13416        m_it_session.ITAdvance();
13417
13418    ARMOpcode *opcode_data = NULL;
13419
13420    if (m_opcode_mode == eModeThumb)
13421        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13422    else if (m_opcode_mode == eModeARM)
13423        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13424
13425    if (opcode_data == NULL)
13426        return false;
13427
13428    const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13429    m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13430
13431    bool success = false;
13432    if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13433    {
13434        m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13435                                                dwarf_cpsr,
13436                                                0,
13437                                                &success);
13438    }
13439
13440    // Only return false if we are unable to read the CPSR if we care about conditions
13441    if (success == false && m_ignore_conditions == false)
13442        return false;
13443
13444    uint32_t orig_pc_value = 0;
13445    if (auto_advance_pc)
13446    {
13447        orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13448        if (!success)
13449            return false;
13450    }
13451
13452    // Call the Emulate... function.
13453    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13454    if (!success)
13455        return false;
13456
13457    if (auto_advance_pc)
13458    {
13459        uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13460        if (!success)
13461            return false;
13462
13463        if (auto_advance_pc && (after_pc_value == orig_pc_value))
13464        {
13465            if (opcode_data->size == eSize32)
13466                after_pc_value += 4;
13467            else if (opcode_data->size == eSize16)
13468                after_pc_value += 2;
13469
13470            EmulateInstruction::Context context;
13471            context.type = eContextAdvancePC;
13472            context.SetNoArgs();
13473            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13474                return false;
13475
13476        }
13477    }
13478    return true;
13479}
13480
13481bool
13482EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13483{
13484    if (!test_data)
13485    {
13486        out_stream->Printf ("TestEmulation: Missing test data.\n");
13487        return false;
13488    }
13489
13490    static ConstString opcode_key ("opcode");
13491    static ConstString before_key ("before_state");
13492    static ConstString after_key ("after_state");
13493
13494    OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13495
13496    uint32_t test_opcode;
13497    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13498    {
13499        out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13500        return false;
13501    }
13502    test_opcode = value_sp->GetUInt64Value ();
13503
13504    if (arch.GetTriple().getArch() == llvm::Triple::arm)
13505    {
13506        m_opcode_mode = eModeARM;
13507        m_opcode.SetOpcode32 (test_opcode);
13508    }
13509    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13510    {
13511        m_opcode_mode = eModeThumb;
13512        if (test_opcode < 0x10000)
13513            m_opcode.SetOpcode16 (test_opcode);
13514        else
13515            m_opcode.SetOpcode32 (test_opcode);
13516
13517    }
13518    else
13519    {
13520        out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13521        return false;
13522    }
13523
13524    EmulationStateARM before_state;
13525    EmulationStateARM after_state;
13526
13527    value_sp = test_data->GetValueForKey (before_key);
13528    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13529    {
13530        out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13531        return false;
13532    }
13533
13534    OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13535    if (!before_state.LoadStateFromDictionary (state_dictionary))
13536    {
13537        out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13538        return false;
13539    }
13540
13541    value_sp = test_data->GetValueForKey (after_key);
13542    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13543    {
13544        out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13545        return false;
13546    }
13547
13548    state_dictionary = value_sp->GetAsDictionary ();
13549    if (!after_state.LoadStateFromDictionary (state_dictionary))
13550    {
13551        out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13552        return false;
13553    }
13554
13555    SetBaton ((void *) &before_state);
13556    SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13557                  &EmulationStateARM::WritePseudoMemory,
13558                  &EmulationStateARM::ReadPseudoRegister,
13559                  &EmulationStateARM::WritePseudoRegister);
13560
13561    bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13562    if (!success)
13563    {
13564        out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13565        return false;
13566    }
13567
13568    success = before_state.CompareState (after_state);
13569    if (!success)
13570        out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13571
13572    return success;
13573}
13574//
13575//
13576//const char *
13577//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13578//{
13579//    if (reg_kind == eRegisterKindGeneric)
13580//    {
13581//        switch (reg_num)
13582//        {
13583//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13584//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13585//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13586//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13587//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13588//        default: return NULL;
13589//        }
13590//    }
13591//    else if (reg_kind == eRegisterKindDWARF)
13592//    {
13593//        return GetARMDWARFRegisterName (reg_num);
13594//    }
13595//    return NULL;
13596//}
13597//
13598bool
13599EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13600{
13601    unwind_plan.Clear();
13602    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13603
13604    UnwindPlan::RowSP row(new UnwindPlan::Row);
13605
13606    // Our previous Call Frame Address is the stack pointer
13607    row->SetCFARegister (dwarf_sp);
13608
13609    // Our previous PC is in the LR
13610    row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13611    unwind_plan.AppendRow (row);
13612
13613    // All other registers are the same.
13614
13615    unwind_plan.SetSourceName ("EmulateInstructionARM");
13616    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13617    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13618    return true;
13619}
13620