EmulateInstructionARM.cpp revision 269024
1312303Sngie//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2312303Sngie//
3312303Sngie//                     The LLVM Compiler Infrastructure
4312303Sngie//
5312303Sngie// This file is distributed under the University of Illinois Open Source
6312303Sngie// License. See LICENSE.TXT for details.
7312303Sngie//
8312303Sngie//===----------------------------------------------------------------------===//
9312303Sngie
10312303Sngie#include <stdlib.h>
11312303Sngie
12312303Sngie#include "EmulateInstructionARM.h"
13312303Sngie#include "EmulationStateARM.h"
14312303Sngie#include "lldb/Core/ArchSpec.h"
15312303Sngie#include "lldb/Core/Address.h"
16312303Sngie#include "lldb/Core/ConstString.h"
17312303Sngie#include "lldb/Core/PluginManager.h"
18312303Sngie#include "lldb/Core/Stream.h"
19312303Sngie#include "lldb/Interpreter/OptionValueArray.h"
20312303Sngie#include "lldb/Interpreter/OptionValueDictionary.h"
21312303Sngie#include "lldb/Symbol/UnwindPlan.h"
22312303Sngie
23312303Sngie#include "Plugins/Process/Utility/ARMDefines.h"
24312303Sngie#include "Plugins/Process/Utility/ARMUtils.h"
25312303Sngie#include "Utility/ARM_DWARF_Registers.h"
26312303Sngie
27312303Sngie#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
28312303Sngie                                     // and countTrailingZeros function
29312303Sngie
30312303Sngieusing namespace lldb;
31312303Sngieusing namespace lldb_private;
32312303Sngie
33312303Sngie// Convenient macro definitions.
34312303Sngie#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35312303Sngie#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36313404Sngie
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#ifdef LLDB_CONFIGURATION_DEBUG
54        printf("Encoding error: IT Mask '0000'\n");
55#endif
56        return 0;
57    }
58    return (4 - TZ);
59}
60
61// Init ITState.  Note that at least one bit is always 1 in mask.
62bool ITSession::InitIT(uint32_t bits7_0)
63{
64    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
65    if (ITCounter == 0)
66        return false;
67
68    // A8.6.50 IT
69    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
70    if (FirstCond == 0xF)
71    {
72#ifdef LLDB_CONFIGURATION_DEBUG
73        printf("Encoding error: IT FirstCond '1111'\n");
74#endif
75        return false;
76    }
77    if (FirstCond == 0xE && ITCounter != 1)
78    {
79#ifdef LLDB_CONFIGURATION_DEBUG
80        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
81#endif
82        return false;
83    }
84
85    ITState = bits7_0;
86    return true;
87}
88
89// Update ITState if necessary.
90void ITSession::ITAdvance()
91{
92    //assert(ITCounter);
93    --ITCounter;
94    if (ITCounter == 0)
95        ITState = 0;
96    else
97    {
98        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
99        SetBits32(ITState, 4, 0, NewITState4_0);
100    }
101}
102
103// Return true if we're inside an IT Block.
104bool ITSession::InITBlock()
105{
106    return ITCounter != 0;
107}
108
109// Return true if we're the last instruction inside an IT Block.
110bool ITSession::LastInITBlock()
111{
112    return ITCounter == 1;
113}
114
115// Get condition bits for the current thumb instruction.
116uint32_t ITSession::GetCond()
117{
118    if (InITBlock())
119        return Bits32(ITState, 7, 4);
120    else
121        return COND_AL;
122}
123
124// ARM constants used during decoding
125#define REG_RD          0
126#define LDM_REGLIST     1
127#define SP_REG          13
128#define LR_REG          14
129#define PC_REG          15
130#define PC_REGLIST_BIT  0x8000
131
132#define ARMv4     (1u << 0)
133#define ARMv4T    (1u << 1)
134#define ARMv5T    (1u << 2)
135#define ARMv5TE   (1u << 3)
136#define ARMv5TEJ  (1u << 4)
137#define ARMv6     (1u << 5)
138#define ARMv6K    (1u << 6)
139#define ARMv6T2   (1u << 7)
140#define ARMv7     (1u << 8)
141#define ARMv7S    (1u << 9)
142#define ARMv8     (1u << 10)
143#define ARMvAll   (0xffffffffu)
144
145#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
146#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
147#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
148#define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
149#define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
150#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
151#define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
152
153#define No_VFP  0
154#define VFPv1   (1u << 1)
155#define VFPv2   (1u << 2)
156#define VFPv3   (1u << 3)
157#define AdvancedSIMD (1u << 4)
158
159#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
160#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
161#define VFPv2v3     (VFPv2 | VFPv3)
162
163//----------------------------------------------------------------------
164//
165// EmulateInstructionARM implementation
166//
167//----------------------------------------------------------------------
168
169void
170EmulateInstructionARM::Initialize ()
171{
172    PluginManager::RegisterPlugin (GetPluginNameStatic (),
173                                   GetPluginDescriptionStatic (),
174                                   CreateInstance);
175}
176
177void
178EmulateInstructionARM::Terminate ()
179{
180    PluginManager::UnregisterPlugin (CreateInstance);
181}
182
183ConstString
184EmulateInstructionARM::GetPluginNameStatic ()
185{
186    static ConstString g_name("arm");
187    return g_name;
188}
189
190const char *
191EmulateInstructionARM::GetPluginDescriptionStatic ()
192{
193    return "Emulate instructions for the ARM architecture.";
194}
195
196EmulateInstruction *
197EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
198{
199    if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
200    {
201        if (arch.GetTriple().getArch() == llvm::Triple::arm)
202        {
203            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
204
205            if (emulate_insn_ap.get())
206                return emulate_insn_ap.release();
207        }
208        else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
209        {
210            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
211
212            if (emulate_insn_ap.get())
213                return emulate_insn_ap.release();
214        }
215    }
216
217    return NULL;
218}
219
220bool
221EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
222{
223    if (arch.GetTriple().getArch () == llvm::Triple::arm)
224        return true;
225    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
226        return true;
227
228    return false;
229}
230
231// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
232bool
233EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
234{
235    EmulateInstruction::Context context;
236    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
237    context.SetNoArgs ();
238
239    uint32_t random_data = rand ();
240    const uint32_t addr_byte_size = GetAddressByteSize();
241
242    if (!MemAWrite (context, address, random_data, addr_byte_size))
243        return false;
244
245    return true;
246}
247
248// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
249bool
250EmulateInstructionARM::WriteBits32Unknown (int n)
251{
252    EmulateInstruction::Context context;
253    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
254    context.SetNoArgs ();
255
256    bool success;
257    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
258
259    if (!success)
260        return false;
261
262    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
263        return false;
264
265    return true;
266}
267
268bool
269EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
270{
271    if (reg_kind == eRegisterKindGeneric)
272    {
273        switch (reg_num)
274        {
275            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
276            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
277            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
278            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
279            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
280            default: return false;
281        }
282    }
283
284    if (reg_kind == eRegisterKindDWARF)
285        return GetARMDWARFRegisterInfo(reg_num, reg_info);
286    return false;
287}
288
289uint32_t
290EmulateInstructionARM::GetFramePointerRegisterNumber () const
291{
292    bool is_apple = false;
293    if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
294        is_apple = true;
295    switch (m_arch.GetTriple().getOS())
296    {
297            case llvm::Triple::Darwin:
298            case llvm::Triple::MacOSX:
299            case llvm::Triple::IOS:
300                is_apple = true;
301                break;
302            default:
303                break;
304    }
305
306    /* On Apple iOS et al, the frame pointer register is always r7.
307     * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
308     */
309
310    uint32_t fp_regnum = 11;
311
312    if (is_apple)
313        fp_regnum = 7;
314
315    if (m_opcode_mode == eModeThumb)
316        fp_regnum = 7;
317
318    return fp_regnum;
319}
320
321uint32_t
322EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
323{
324    bool is_apple = false;
325    if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
326        is_apple = true;
327    switch (m_arch.GetTriple().getOS())
328    {
329            case llvm::Triple::Darwin:
330            case llvm::Triple::MacOSX:
331            case llvm::Triple::IOS:
332                is_apple = true;
333                break;
334            default:
335                break;
336    }
337
338    /* On Apple iOS et al, the frame pointer register is always r7.
339     * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
340     */
341
342    uint32_t fp_regnum = dwarf_r11;
343
344    if (is_apple)
345        fp_regnum = dwarf_r7;
346
347    if (m_opcode_mode == eModeThumb)
348        fp_regnum = dwarf_r7;
349
350    return fp_regnum;
351}
352
353// Push Multiple Registers stores multiple registers to the stack, storing to
354// consecutive memory locations ending just below the address in SP, and updates
355// SP to point to the start of the stored data.
356bool
357EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
358{
359#if 0
360    // ARM pseudo code...
361    if (ConditionPassed())
362    {
363        EncodingSpecificOperations();
364        NullCheckIfThumbEE(13);
365        address = SP - 4*BitCount(registers);
366
367        for (i = 0 to 14)
368        {
369            if (registers<i> == '1')
370            {
371                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
372                    MemA[address,4] = bits(32) UNKNOWN;
373                else
374                    MemA[address,4] = R[i];
375                address = address + 4;
376            }
377        }
378
379        if (registers<15> == '1') // Only possible for encoding A1 or A2
380            MemA[address,4] = PCStoreValue();
381
382        SP = SP - 4*BitCount(registers);
383    }
384#endif
385
386    bool conditional = false;
387    bool success = false;
388    if (ConditionPassed(opcode, &conditional))
389    {
390        const uint32_t addr_byte_size = GetAddressByteSize();
391        const addr_t sp = ReadCoreReg (SP_REG, &success);
392        if (!success)
393            return false;
394        uint32_t registers = 0;
395        uint32_t Rt; // the source register
396        switch (encoding) {
397        case eEncodingT1:
398            registers = Bits32(opcode, 7, 0);
399            // The M bit represents LR.
400            if (Bit32(opcode, 8))
401                registers |= (1u << 14);
402            // if BitCount(registers) < 1 then UNPREDICTABLE;
403            if (BitCount(registers) < 1)
404                return false;
405            break;
406        case eEncodingT2:
407            // Ignore bits 15 & 13.
408            registers = Bits32(opcode, 15, 0) & ~0xa000;
409            // if BitCount(registers) < 2 then UNPREDICTABLE;
410            if (BitCount(registers) < 2)
411                return false;
412            break;
413        case eEncodingT3:
414            Rt = Bits32(opcode, 15, 12);
415            // if BadReg(t) then UNPREDICTABLE;
416            if (BadReg(Rt))
417                return false;
418            registers = (1u << Rt);
419            break;
420        case eEncodingA1:
421            registers = Bits32(opcode, 15, 0);
422            // Instead of return false, let's handle the following case as well,
423            // which amounts to pushing one reg onto the full descending stacks.
424            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
425            break;
426        case eEncodingA2:
427            Rt = Bits32(opcode, 15, 12);
428            // if t == 13 then UNPREDICTABLE;
429            if (Rt == dwarf_sp)
430                return false;
431            registers = (1u << Rt);
432            break;
433        default:
434            return false;
435        }
436        addr_t sp_offset = addr_byte_size * BitCount (registers);
437        addr_t addr = sp - sp_offset;
438        uint32_t i;
439
440        EmulateInstruction::Context context;
441        if (conditional)
442            context.type = EmulateInstruction::eContextRegisterStore;
443        else
444            context.type = EmulateInstruction::eContextPushRegisterOnStack;
445        RegisterInfo reg_info;
446        RegisterInfo sp_reg;
447        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
448        for (i=0; i<15; ++i)
449        {
450            if (BitIsSet (registers, i))
451            {
452                GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
453                context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
454                uint32_t reg_value = ReadCoreReg(i, &success);
455                if (!success)
456                    return false;
457                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
458                    return false;
459                addr += addr_byte_size;
460            }
461        }
462
463        if (BitIsSet (registers, 15))
464        {
465            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
466            context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
467            const uint32_t pc = ReadCoreReg(PC_REG, &success);
468            if (!success)
469                return false;
470            if (!MemAWrite (context, addr, pc, addr_byte_size))
471                return false;
472        }
473
474        context.type = EmulateInstruction::eContextAdjustStackPointer;
475        context.SetImmediateSigned (-sp_offset);
476
477        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
478            return false;
479    }
480    return true;
481}
482
483// Pop Multiple Registers loads multiple registers from the stack, loading from
484// consecutive memory locations staring at the address in SP, and updates
485// SP to point just above the loaded data.
486bool
487EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
488{
489#if 0
490    // ARM pseudo code...
491    if (ConditionPassed())
492    {
493        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
494        address = SP;
495        for i = 0 to 14
496            if registers<i> == '1' then
497                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
498        if registers<15> == '1' then
499            if UnalignedAllowed then
500                LoadWritePC(MemU[address,4]);
501            else
502                LoadWritePC(MemA[address,4]);
503        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
504        if registers<13> == '1' then SP = bits(32) UNKNOWN;
505    }
506#endif
507
508    bool success = false;
509
510    bool conditional = false;
511    if (ConditionPassed(opcode, &conditional))
512    {
513        const uint32_t addr_byte_size = GetAddressByteSize();
514        const addr_t sp = ReadCoreReg (SP_REG, &success);
515        if (!success)
516            return false;
517        uint32_t registers = 0;
518        uint32_t Rt; // the destination register
519        switch (encoding) {
520        case eEncodingT1:
521            registers = Bits32(opcode, 7, 0);
522            // The P bit represents PC.
523            if (Bit32(opcode, 8))
524                registers |= (1u << 15);
525            // if BitCount(registers) < 1 then UNPREDICTABLE;
526            if (BitCount(registers) < 1)
527                return false;
528            break;
529        case eEncodingT2:
530            // Ignore bit 13.
531            registers = Bits32(opcode, 15, 0) & ~0x2000;
532            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
533            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
534                return false;
535            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
536            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
537                return false;
538            break;
539        case eEncodingT3:
540            Rt = Bits32(opcode, 15, 12);
541            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
542            if (Rt == 13)
543                return false;
544            if (Rt == 15 && InITBlock() && !LastInITBlock())
545                return false;
546            registers = (1u << Rt);
547            break;
548        case eEncodingA1:
549            registers = Bits32(opcode, 15, 0);
550            // Instead of return false, let's handle the following case as well,
551            // which amounts to popping one reg from the full descending stacks.
552            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
553
554            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
555            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
556                return false;
557            break;
558        case eEncodingA2:
559            Rt = Bits32(opcode, 15, 12);
560            // if t == 13 then UNPREDICTABLE;
561            if (Rt == dwarf_sp)
562                return false;
563            registers = (1u << Rt);
564            break;
565        default:
566            return false;
567        }
568        addr_t sp_offset = addr_byte_size * BitCount (registers);
569        addr_t addr = sp;
570        uint32_t i, data;
571
572        EmulateInstruction::Context context;
573        if (conditional)
574            context.type = EmulateInstruction::eContextRegisterLoad;
575        else
576            context.type = EmulateInstruction::eContextPopRegisterOffStack;
577
578        RegisterInfo sp_reg;
579        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
580
581        for (i=0; i<15; ++i)
582        {
583            if (BitIsSet (registers, i))
584            {
585                context.SetRegisterPlusOffset (sp_reg, addr - sp);
586                data = MemARead(context, addr, 4, 0, &success);
587                if (!success)
588                    return false;
589                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
590                    return false;
591                addr += addr_byte_size;
592            }
593        }
594
595        if (BitIsSet (registers, 15))
596        {
597            context.SetRegisterPlusOffset (sp_reg, addr - sp);
598            data = MemARead(context, addr, 4, 0, &success);
599            if (!success)
600                return false;
601            // In ARMv5T and above, this is an interworking branch.
602            if (!LoadWritePC(context, data))
603                return false;
604            //addr += addr_byte_size;
605        }
606
607        context.type = EmulateInstruction::eContextAdjustStackPointer;
608        context.SetImmediateSigned (sp_offset);
609
610        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
611            return false;
612    }
613    return true;
614}
615
616// Set r7 or ip to point to saved value residing within the stack.
617// ADD (SP plus immediate)
618bool
619EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
620{
621#if 0
622    // ARM pseudo code...
623    if (ConditionPassed())
624    {
625        EncodingSpecificOperations();
626        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
627        if d == 15 then
628           ALUWritePC(result); // setflags is always FALSE here
629        else
630            R[d] = result;
631            if setflags then
632                APSR.N = result<31>;
633                APSR.Z = IsZeroBit(result);
634                APSR.C = carry;
635                APSR.V = overflow;
636    }
637#endif
638
639    bool success = false;
640
641    if (ConditionPassed(opcode))
642    {
643        const addr_t sp = ReadCoreReg (SP_REG, &success);
644        if (!success)
645            return false;
646        uint32_t Rd; // the destination register
647        uint32_t imm32;
648        switch (encoding) {
649        case eEncodingT1:
650            Rd = 7;
651            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
652            break;
653        case eEncodingA1:
654            Rd = Bits32(opcode, 15, 12);
655            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
656            break;
657        default:
658            return false;
659        }
660        addr_t sp_offset = imm32;
661        addr_t addr = sp + sp_offset; // a pointer to the stack area
662
663        EmulateInstruction::Context context;
664        context.type = eContextSetFramePointer;
665        RegisterInfo sp_reg;
666        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
667        context.SetRegisterPlusOffset (sp_reg, sp_offset);
668
669        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
670            return false;
671    }
672    return true;
673}
674
675// Set r7 or ip to the current stack pointer.
676// MOV (register)
677bool
678EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
679{
680#if 0
681    // ARM pseudo code...
682    if (ConditionPassed())
683    {
684        EncodingSpecificOperations();
685        result = R[m];
686        if d == 15 then
687            ALUWritePC(result); // setflags is always FALSE here
688        else
689            R[d] = result;
690            if setflags then
691                APSR.N = result<31>;
692                APSR.Z = IsZeroBit(result);
693                // APSR.C unchanged
694                // APSR.V unchanged
695    }
696#endif
697
698    bool success = false;
699
700    if (ConditionPassed(opcode))
701    {
702        const addr_t sp = ReadCoreReg (SP_REG, &success);
703        if (!success)
704            return false;
705        uint32_t Rd; // the destination register
706        switch (encoding) {
707        case eEncodingT1:
708            Rd = 7;
709            break;
710        case eEncodingA1:
711            Rd = 12;
712            break;
713        default:
714            return false;
715        }
716
717        EmulateInstruction::Context context;
718        if (Rd == GetFramePointerRegisterNumber())
719            context.type = EmulateInstruction::eContextSetFramePointer;
720        else
721            context.type = EmulateInstruction::eContextRegisterPlusOffset;
722        RegisterInfo sp_reg;
723        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
724        context.SetRegisterPlusOffset (sp_reg, 0);
725
726        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
727            return false;
728    }
729    return true;
730}
731
732// Move from high register (r8-r15) to low register (r0-r7).
733// MOV (register)
734bool
735EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
736{
737    return EmulateMOVRdRm (opcode, encoding);
738}
739
740// Move from register to register.
741// MOV (register)
742bool
743EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
744{
745#if 0
746    // ARM pseudo code...
747    if (ConditionPassed())
748    {
749        EncodingSpecificOperations();
750        result = R[m];
751        if d == 15 then
752            ALUWritePC(result); // setflags is always FALSE here
753        else
754            R[d] = result;
755            if setflags then
756                APSR.N = result<31>;
757                APSR.Z = IsZeroBit(result);
758                // APSR.C unchanged
759                // APSR.V unchanged
760    }
761#endif
762
763    bool success = false;
764
765    if (ConditionPassed(opcode))
766    {
767        uint32_t Rm; // the source register
768        uint32_t Rd; // the destination register
769        bool setflags;
770        switch (encoding) {
771        case eEncodingT1:
772            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
773            Rm = Bits32(opcode, 6, 3);
774            setflags = false;
775            if (Rd == 15 && InITBlock() && !LastInITBlock())
776                return false;
777            break;
778        case eEncodingT2:
779            Rd = Bits32(opcode, 2, 0);
780            Rm = Bits32(opcode, 5, 3);
781            setflags = true;
782            if (InITBlock())
783                return false;
784            break;
785        case eEncodingT3:
786            Rd = Bits32(opcode, 11, 8);
787            Rm = Bits32(opcode, 3, 0);
788            setflags = BitIsSet(opcode, 20);
789            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
790            if (setflags && (BadReg(Rd) || BadReg(Rm)))
791                return false;
792            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
793            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
794                return false;
795            break;
796        case eEncodingA1:
797            Rd = Bits32(opcode, 15, 12);
798            Rm = Bits32(opcode, 3, 0);
799            setflags = BitIsSet(opcode, 20);
800
801            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
802            if (Rd == 15 && setflags)
803                return EmulateSUBSPcLrEtc (opcode, encoding);
804            break;
805        default:
806            return false;
807        }
808        uint32_t result = ReadCoreReg(Rm, &success);
809        if (!success)
810            return false;
811
812        // The context specifies that Rm is to be moved into Rd.
813        EmulateInstruction::Context context;
814        context.type = EmulateInstruction::eContextRegisterLoad;
815        RegisterInfo dwarf_reg;
816        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
817        context.SetRegister (dwarf_reg);
818
819        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
820            return false;
821    }
822    return true;
823}
824
825// Move (immediate) writes an immediate value to the destination register.  It
826// can optionally update the condition flags based on the value.
827// MOV (immediate)
828bool
829EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
830{
831#if 0
832    // ARM pseudo code...
833    if (ConditionPassed())
834    {
835        EncodingSpecificOperations();
836        result = imm32;
837        if d == 15 then         // Can only occur for ARM encoding
838            ALUWritePC(result); // setflags is always FALSE here
839        else
840            R[d] = result;
841            if setflags then
842                APSR.N = result<31>;
843                APSR.Z = IsZeroBit(result);
844                APSR.C = carry;
845                // APSR.V unchanged
846    }
847#endif
848
849    if (ConditionPassed(opcode))
850    {
851        uint32_t Rd; // the destination register
852        uint32_t imm32; // the immediate value to be written to Rd
853        uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
854                            // for setflags == false, this value is a don't care
855                            // initialized to 0 to silence the static analyzer
856        bool setflags;
857        switch (encoding) {
858            case eEncodingT1:
859                Rd = Bits32(opcode, 10, 8);
860                setflags = !InITBlock();
861                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
862                carry = APSR_C;
863
864                break;
865
866            case eEncodingT2:
867                Rd = Bits32(opcode, 11, 8);
868                setflags = BitIsSet(opcode, 20);
869                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
870                if (BadReg(Rd))
871                  return false;
872
873                break;
874
875            case eEncodingT3:
876            {
877                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
878                Rd = Bits32 (opcode, 11, 8);
879                setflags = false;
880                uint32_t imm4 = Bits32 (opcode, 19, 16);
881                uint32_t imm3 = Bits32 (opcode, 14, 12);
882                uint32_t i = Bit32 (opcode, 26);
883                uint32_t imm8 = Bits32 (opcode, 7, 0);
884                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
885
886                // if BadReg(d) then UNPREDICTABLE;
887                if (BadReg (Rd))
888                    return false;
889            }
890                break;
891
892            case eEncodingA1:
893                // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
894                Rd = Bits32 (opcode, 15, 12);
895                setflags = BitIsSet (opcode, 20);
896                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
897
898                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
899                if ((Rd == 15) && setflags)
900                    return EmulateSUBSPcLrEtc (opcode, encoding);
901
902                break;
903
904            case eEncodingA2:
905            {
906                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
907                Rd = Bits32 (opcode, 15, 12);
908                setflags = false;
909                uint32_t imm4 = Bits32 (opcode, 19, 16);
910                uint32_t imm12 = Bits32 (opcode, 11, 0);
911                imm32 = (imm4 << 12) | imm12;
912
913                // if d == 15 then UNPREDICTABLE;
914                if (Rd == 15)
915                    return false;
916            }
917                break;
918
919            default:
920                return false;
921        }
922        uint32_t result = imm32;
923
924        // The context specifies that an immediate is to be moved into Rd.
925        EmulateInstruction::Context context;
926        context.type = EmulateInstruction::eContextImmediate;
927        context.SetNoArgs ();
928
929        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
930            return false;
931    }
932    return true;
933}
934
935// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
936// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
937// unsigned values.
938//
939// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
940// limited to only a few forms of the instruction.
941bool
942EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
943{
944#if 0
945    if ConditionPassed() then
946        EncodingSpecificOperations();
947        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
948        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
949        result = operand1 * operand2;
950        R[d] = result<31:0>;
951        if setflags then
952            APSR.N = result<31>;
953            APSR.Z = IsZeroBit(result);
954            if ArchVersion() == 4 then
955                APSR.C = bit UNKNOWN;
956            // else APSR.C unchanged
957            // APSR.V always unchanged
958#endif
959
960    if (ConditionPassed(opcode))
961    {
962        uint32_t d;
963        uint32_t n;
964        uint32_t m;
965        bool setflags;
966
967        // EncodingSpecificOperations();
968        switch (encoding)
969        {
970            case eEncodingT1:
971                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
972                d = Bits32 (opcode, 2, 0);
973                n = Bits32 (opcode, 5, 3);
974                m = Bits32 (opcode, 2, 0);
975                setflags = !InITBlock();
976
977                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
978                if ((ArchVersion() < ARMv6) && (d == n))
979                    return false;
980
981                break;
982
983            case eEncodingT2:
984                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
985                d = Bits32 (opcode, 11, 8);
986                n = Bits32 (opcode, 19, 16);
987                m = Bits32 (opcode, 3, 0);
988                setflags = false;
989
990                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
991                if (BadReg (d) || BadReg (n) || BadReg (m))
992                    return false;
993
994                break;
995
996            case eEncodingA1:
997                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
998                d = Bits32 (opcode, 19, 16);
999                n = Bits32 (opcode, 3, 0);
1000                m = Bits32 (opcode, 11, 8);
1001                setflags = BitIsSet (opcode, 20);
1002
1003                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1004                if ((d == 15) ||  (n == 15) || (m == 15))
1005                    return false;
1006
1007                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1008                if ((ArchVersion() < ARMv6) && (d == n))
1009                    return false;
1010
1011                break;
1012
1013            default:
1014                return false;
1015        }
1016
1017        bool success = false;
1018
1019        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1020        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1021        if (!success)
1022            return false;
1023
1024        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1025        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1026        if (!success)
1027            return false;
1028
1029        // result = operand1 * operand2;
1030        uint64_t result = operand1 * operand2;
1031
1032        // R[d] = result<31:0>;
1033        RegisterInfo op1_reg;
1034        RegisterInfo op2_reg;
1035        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1036        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1037
1038        EmulateInstruction::Context context;
1039        context.type = eContextArithmetic;
1040        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1041
1042        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1043            return false;
1044
1045        // if setflags then
1046        if (setflags)
1047        {
1048            // APSR.N = result<31>;
1049            // APSR.Z = IsZeroBit(result);
1050            m_new_inst_cpsr = m_opcode_cpsr;
1051            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1052            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1053            if (m_new_inst_cpsr != m_opcode_cpsr)
1054            {
1055                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1056                    return false;
1057            }
1058
1059            // if ArchVersion() == 4 then
1060                // APSR.C = bit UNKNOWN;
1061        }
1062    }
1063    return true;
1064}
1065
1066// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1067// It can optionally update the condition flags based on the value.
1068bool
1069EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1070{
1071#if 0
1072    // ARM pseudo code...
1073    if (ConditionPassed())
1074    {
1075        EncodingSpecificOperations();
1076        result = NOT(imm32);
1077        if d == 15 then         // Can only occur for ARM encoding
1078            ALUWritePC(result); // setflags is always FALSE here
1079        else
1080            R[d] = result;
1081            if setflags then
1082                APSR.N = result<31>;
1083                APSR.Z = IsZeroBit(result);
1084                APSR.C = carry;
1085                // APSR.V unchanged
1086    }
1087#endif
1088
1089    if (ConditionPassed(opcode))
1090    {
1091        uint32_t Rd; // the destination register
1092        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1093        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1094        bool setflags;
1095        switch (encoding) {
1096        case eEncodingT1:
1097            Rd = Bits32(opcode, 11, 8);
1098            setflags = BitIsSet(opcode, 20);
1099            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1100            break;
1101        case eEncodingA1:
1102            Rd = Bits32(opcode, 15, 12);
1103            setflags = BitIsSet(opcode, 20);
1104            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1105
1106            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1107            if (Rd == 15 && setflags)
1108                return EmulateSUBSPcLrEtc (opcode, encoding);
1109            break;
1110        default:
1111            return false;
1112        }
1113        uint32_t result = ~imm32;
1114
1115        // The context specifies that an immediate is to be moved into Rd.
1116        EmulateInstruction::Context context;
1117        context.type = EmulateInstruction::eContextImmediate;
1118        context.SetNoArgs ();
1119
1120        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1121            return false;
1122    }
1123    return true;
1124}
1125
1126// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1127// It can optionally update the condition flags based on the result.
1128bool
1129EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1130{
1131#if 0
1132    // ARM pseudo code...
1133    if (ConditionPassed())
1134    {
1135        EncodingSpecificOperations();
1136        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1137        result = NOT(shifted);
1138        if d == 15 then         // Can only occur for ARM encoding
1139            ALUWritePC(result); // setflags is always FALSE here
1140        else
1141            R[d] = result;
1142            if setflags then
1143                APSR.N = result<31>;
1144                APSR.Z = IsZeroBit(result);
1145                APSR.C = carry;
1146                // APSR.V unchanged
1147    }
1148#endif
1149
1150    if (ConditionPassed(opcode))
1151    {
1152        uint32_t Rm; // the source register
1153        uint32_t Rd; // the destination register
1154        ARM_ShifterType shift_t;
1155        uint32_t shift_n; // the shift applied to the value read from Rm
1156        bool setflags;
1157        uint32_t carry; // the carry bit after the shift operation
1158        switch (encoding) {
1159        case eEncodingT1:
1160            Rd = Bits32(opcode, 2, 0);
1161            Rm = Bits32(opcode, 5, 3);
1162            setflags = !InITBlock();
1163            shift_t = SRType_LSL;
1164            shift_n = 0;
1165            if (InITBlock())
1166                return false;
1167            break;
1168        case eEncodingT2:
1169            Rd = Bits32(opcode, 11, 8);
1170            Rm = Bits32(opcode, 3, 0);
1171            setflags = BitIsSet(opcode, 20);
1172            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1173            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1174            if (BadReg(Rd) || BadReg(Rm))
1175                return false;
1176            break;
1177        case eEncodingA1:
1178            Rd = Bits32(opcode, 15, 12);
1179            Rm = Bits32(opcode, 3, 0);
1180            setflags = BitIsSet(opcode, 20);
1181            shift_n = DecodeImmShiftARM(opcode, shift_t);
1182            break;
1183        default:
1184            return false;
1185        }
1186        bool success = false;
1187        uint32_t value = ReadCoreReg(Rm, &success);
1188        if (!success)
1189            return false;
1190
1191        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1192        if (!success)
1193            return false;
1194        uint32_t result = ~shifted;
1195
1196        // The context specifies that an immediate is to be moved into Rd.
1197        EmulateInstruction::Context context;
1198        context.type = EmulateInstruction::eContextImmediate;
1199        context.SetNoArgs ();
1200
1201        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1202            return false;
1203    }
1204    return true;
1205}
1206
1207// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1208// LDR (literal)
1209bool
1210EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1211{
1212#if 0
1213    // ARM pseudo code...
1214    if (ConditionPassed())
1215    {
1216        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1217        base = Align(PC,4);
1218        address = if add then (base + imm32) else (base - imm32);
1219        data = MemU[address,4];
1220        if t == 15 then
1221            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1222        elsif UnalignedSupport() || address<1:0> = '00' then
1223            R[t] = data;
1224        else // Can only apply before ARMv7
1225            if CurrentInstrSet() == InstrSet_ARM then
1226                R[t] = ROR(data, 8*UInt(address<1:0>));
1227            else
1228                R[t] = bits(32) UNKNOWN;
1229    }
1230#endif
1231
1232    if (ConditionPassed(opcode))
1233    {
1234        bool success = false;
1235        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1236        if (!success)
1237            return false;
1238
1239        // PC relative immediate load context
1240        EmulateInstruction::Context context;
1241        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1242        RegisterInfo pc_reg;
1243        GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1244        context.SetRegisterPlusOffset (pc_reg, 0);
1245
1246        uint32_t Rt;    // the destination register
1247        uint32_t imm32; // immediate offset from the PC
1248        bool add;       // +imm32 or -imm32?
1249        addr_t base;    // the base address
1250        addr_t address; // the PC relative address
1251        uint32_t data;  // the literal data value from the PC relative load
1252        switch (encoding) {
1253        case eEncodingT1:
1254            Rt = Bits32(opcode, 10, 8);
1255            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1256            add = true;
1257            break;
1258        case eEncodingT2:
1259            Rt = Bits32(opcode, 15, 12);
1260            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1261            add = BitIsSet(opcode, 23);
1262            if (Rt == 15 && InITBlock() && !LastInITBlock())
1263                return false;
1264            break;
1265        default:
1266            return false;
1267        }
1268
1269        base = Align(pc, 4);
1270        if (add)
1271            address = base + imm32;
1272        else
1273            address = base - imm32;
1274
1275        context.SetRegisterPlusOffset(pc_reg, address - base);
1276        data = MemURead(context, address, 4, 0, &success);
1277        if (!success)
1278            return false;
1279
1280        if (Rt == 15)
1281        {
1282            if (Bits32(address, 1, 0) == 0)
1283            {
1284                // In ARMv5T and above, this is an interworking branch.
1285                if (!LoadWritePC(context, data))
1286                    return false;
1287            }
1288            else
1289                return false;
1290        }
1291        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1292        {
1293            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1294                return false;
1295        }
1296        else // We don't handle ARM for now.
1297            return false;
1298
1299    }
1300    return true;
1301}
1302
1303// An add operation to adjust the SP.
1304// ADD (SP plus immediate)
1305bool
1306EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1307{
1308#if 0
1309    // ARM pseudo code...
1310    if (ConditionPassed())
1311    {
1312        EncodingSpecificOperations();
1313        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1314        if d == 15 then // Can only occur for ARM encoding
1315            ALUWritePC(result); // setflags is always FALSE here
1316        else
1317            R[d] = result;
1318            if setflags then
1319                APSR.N = result<31>;
1320                APSR.Z = IsZeroBit(result);
1321                APSR.C = carry;
1322                APSR.V = overflow;
1323    }
1324#endif
1325
1326    bool success = false;
1327
1328    if (ConditionPassed(opcode))
1329    {
1330        const addr_t sp = ReadCoreReg (SP_REG, &success);
1331        if (!success)
1332            return false;
1333        uint32_t imm32; // the immediate operand
1334        uint32_t d;
1335        //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1336        switch (encoding)
1337        {
1338            case eEncodingT1:
1339                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1340                d = Bits32 (opcode, 10, 8);
1341                imm32 = (Bits32 (opcode, 7, 0) << 2);
1342
1343                break;
1344
1345            case eEncodingT2:
1346                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1347                d = 13;
1348                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1349
1350                break;
1351
1352            default:
1353                return false;
1354        }
1355        addr_t sp_offset = imm32;
1356        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1357
1358        EmulateInstruction::Context context;
1359        context.type = EmulateInstruction::eContextAdjustStackPointer;
1360        RegisterInfo sp_reg;
1361        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1362        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1363
1364        if (d == 15)
1365        {
1366            if (!ALUWritePC (context, addr))
1367                return false;
1368        }
1369        else
1370        {
1371            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1372                return false;
1373
1374            // Add this back if/when support eEncodingT3 eEncodingA1
1375            //if (setflags)
1376            //{
1377            //    APSR.N = result<31>;
1378            //    APSR.Z = IsZeroBit(result);
1379            //    APSR.C = carry;
1380            //    APSR.V = overflow;
1381            //}
1382        }
1383    }
1384    return true;
1385}
1386
1387// An add operation to adjust the SP.
1388// ADD (SP plus register)
1389bool
1390EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1391{
1392#if 0
1393    // ARM pseudo code...
1394    if (ConditionPassed())
1395    {
1396        EncodingSpecificOperations();
1397        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1398        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1399        if d == 15 then
1400            ALUWritePC(result); // setflags is always FALSE here
1401        else
1402            R[d] = result;
1403            if setflags then
1404                APSR.N = result<31>;
1405                APSR.Z = IsZeroBit(result);
1406                APSR.C = carry;
1407                APSR.V = overflow;
1408    }
1409#endif
1410
1411    bool success = false;
1412
1413    if (ConditionPassed(opcode))
1414    {
1415        const addr_t sp = ReadCoreReg (SP_REG, &success);
1416        if (!success)
1417            return false;
1418        uint32_t Rm; // the second operand
1419        switch (encoding) {
1420        case eEncodingT2:
1421            Rm = Bits32(opcode, 6, 3);
1422            break;
1423        default:
1424            return false;
1425        }
1426        int32_t reg_value = ReadCoreReg(Rm, &success);
1427        if (!success)
1428            return false;
1429
1430        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1431
1432        EmulateInstruction::Context context;
1433        context.type = eContextArithmetic;
1434        RegisterInfo sp_reg;
1435        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1436
1437        RegisterInfo other_reg;
1438        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1439        context.SetRegisterRegisterOperands (sp_reg, other_reg);
1440
1441        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1442            return false;
1443    }
1444    return true;
1445}
1446
1447// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1448// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1449// from Thumb to ARM.
1450// BLX (immediate)
1451bool
1452EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1453{
1454#if 0
1455    // ARM pseudo code...
1456    if (ConditionPassed())
1457    {
1458        EncodingSpecificOperations();
1459        if CurrentInstrSet() == InstrSet_ARM then
1460            LR = PC - 4;
1461        else
1462            LR = PC<31:1> : '1';
1463        if targetInstrSet == InstrSet_ARM then
1464            targetAddress = Align(PC,4) + imm32;
1465        else
1466            targetAddress = PC + imm32;
1467        SelectInstrSet(targetInstrSet);
1468        BranchWritePC(targetAddress);
1469    }
1470#endif
1471
1472    bool success = true;
1473
1474    if (ConditionPassed(opcode))
1475    {
1476        EmulateInstruction::Context context;
1477        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1478        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1479        if (!success)
1480            return false;
1481        addr_t lr; // next instruction address
1482        addr_t target; // target address
1483        int32_t imm32; // PC-relative offset
1484        switch (encoding) {
1485        case eEncodingT1:
1486            {
1487            lr = pc | 1u; // return address
1488            uint32_t S = Bit32(opcode, 26);
1489            uint32_t imm10 = Bits32(opcode, 25, 16);
1490            uint32_t J1 = Bit32(opcode, 13);
1491            uint32_t J2 = Bit32(opcode, 11);
1492            uint32_t imm11 = Bits32(opcode, 10, 0);
1493            uint32_t I1 = !(J1 ^ S);
1494            uint32_t I2 = !(J2 ^ S);
1495            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1496            imm32 = llvm::SignExtend32<25>(imm25);
1497            target = pc + imm32;
1498            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1499            if (InITBlock() && !LastInITBlock())
1500                return false;
1501            break;
1502            }
1503        case eEncodingT2:
1504            {
1505            lr = pc | 1u; // return address
1506            uint32_t S = Bit32(opcode, 26);
1507            uint32_t imm10H = Bits32(opcode, 25, 16);
1508            uint32_t J1 = Bit32(opcode, 13);
1509            uint32_t J2 = Bit32(opcode, 11);
1510            uint32_t imm10L = Bits32(opcode, 10, 1);
1511            uint32_t I1 = !(J1 ^ S);
1512            uint32_t I2 = !(J2 ^ S);
1513            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1514            imm32 = llvm::SignExtend32<25>(imm25);
1515            target = Align(pc, 4) + imm32;
1516            context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1517            if (InITBlock() && !LastInITBlock())
1518                return false;
1519            break;
1520            }
1521        case eEncodingA1:
1522            lr = pc - 4; // return address
1523            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1524            target = Align(pc, 4) + imm32;
1525            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1526            break;
1527        case eEncodingA2:
1528            lr = pc - 4; // return address
1529            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1530            target = pc + imm32;
1531            context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1532            break;
1533        default:
1534            return false;
1535        }
1536        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1537            return false;
1538        if (!BranchWritePC(context, target))
1539            return false;
1540    }
1541    return true;
1542}
1543
1544// Branch with Link and Exchange (register) calls a subroutine at an address and
1545// instruction set specified by a register.
1546// BLX (register)
1547bool
1548EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1549{
1550#if 0
1551    // ARM pseudo code...
1552    if (ConditionPassed())
1553    {
1554        EncodingSpecificOperations();
1555        target = R[m];
1556        if CurrentInstrSet() == InstrSet_ARM then
1557            next_instr_addr = PC - 4;
1558            LR = next_instr_addr;
1559        else
1560            next_instr_addr = PC - 2;
1561            LR = next_instr_addr<31:1> : '1';
1562        BXWritePC(target);
1563    }
1564#endif
1565
1566    bool success = false;
1567
1568    if (ConditionPassed(opcode))
1569    {
1570        EmulateInstruction::Context context;
1571        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1572        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1573        addr_t lr; // next instruction address
1574        if (!success)
1575            return false;
1576        uint32_t Rm; // the register with the target address
1577        switch (encoding) {
1578        case eEncodingT1:
1579            lr = (pc - 2) | 1u; // return address
1580            Rm = Bits32(opcode, 6, 3);
1581            // if m == 15 then UNPREDICTABLE;
1582            if (Rm == 15)
1583                return false;
1584            if (InITBlock() && !LastInITBlock())
1585                return false;
1586            break;
1587        case eEncodingA1:
1588            lr = pc - 4; // return address
1589            Rm = Bits32(opcode, 3, 0);
1590            // if m == 15 then UNPREDICTABLE;
1591            if (Rm == 15)
1592                return false;
1593            break;
1594        default:
1595            return false;
1596        }
1597        addr_t target = ReadCoreReg (Rm, &success);
1598        if (!success)
1599            return false;
1600        RegisterInfo dwarf_reg;
1601        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1602        context.SetRegister (dwarf_reg);
1603        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1604            return false;
1605        if (!BXWritePC(context, target))
1606            return false;
1607    }
1608    return true;
1609}
1610
1611// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1612bool
1613EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1614{
1615#if 0
1616    // ARM pseudo code...
1617    if (ConditionPassed())
1618    {
1619        EncodingSpecificOperations();
1620        BXWritePC(R[m]);
1621    }
1622#endif
1623
1624    if (ConditionPassed(opcode))
1625    {
1626        EmulateInstruction::Context context;
1627        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1628        uint32_t Rm; // the register with the target address
1629        switch (encoding) {
1630        case eEncodingT1:
1631            Rm = Bits32(opcode, 6, 3);
1632            if (InITBlock() && !LastInITBlock())
1633                return false;
1634            break;
1635        case eEncodingA1:
1636            Rm = Bits32(opcode, 3, 0);
1637            break;
1638        default:
1639            return false;
1640        }
1641        bool success = false;
1642        addr_t target = ReadCoreReg (Rm, &success);
1643        if (!success)
1644            return false;
1645
1646        RegisterInfo dwarf_reg;
1647        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1648        context.SetRegister (dwarf_reg);
1649        if (!BXWritePC(context, target))
1650            return false;
1651    }
1652    return true;
1653}
1654
1655// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1656// address and instruction set specified by a register as though it were a BX instruction.
1657//
1658// TODO: Emulate Jazelle architecture?
1659//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1660bool
1661EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1662{
1663#if 0
1664    // ARM pseudo code...
1665    if (ConditionPassed())
1666    {
1667        EncodingSpecificOperations();
1668        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1669            BXWritePC(R[m]);
1670        else
1671            if JazelleAcceptsExecution() then
1672                SwitchToJazelleExecution();
1673            else
1674                SUBARCHITECTURE_DEFINED handler call;
1675    }
1676#endif
1677
1678    if (ConditionPassed(opcode))
1679    {
1680        EmulateInstruction::Context context;
1681        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1682        uint32_t Rm; // the register with the target address
1683        switch (encoding) {
1684        case eEncodingT1:
1685            Rm = Bits32(opcode, 19, 16);
1686            if (BadReg(Rm))
1687                return false;
1688            if (InITBlock() && !LastInITBlock())
1689                return false;
1690            break;
1691        case eEncodingA1:
1692            Rm = Bits32(opcode, 3, 0);
1693            if (Rm == 15)
1694                return false;
1695            break;
1696        default:
1697            return false;
1698        }
1699        bool success = false;
1700        addr_t target = ReadCoreReg (Rm, &success);
1701        if (!success)
1702            return false;
1703
1704        RegisterInfo dwarf_reg;
1705        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1706        context.SetRegister (dwarf_reg);
1707        if (!BXWritePC(context, target))
1708            return false;
1709    }
1710    return true;
1711}
1712
1713// Set r7 to point to some ip offset.
1714// SUB (immediate)
1715bool
1716EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1717{
1718#if 0
1719    // ARM pseudo code...
1720    if (ConditionPassed())
1721    {
1722        EncodingSpecificOperations();
1723        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1724        if d == 15 then // Can only occur for ARM encoding
1725           ALUWritePC(result); // setflags is always FALSE here
1726        else
1727            R[d] = result;
1728            if setflags then
1729                APSR.N = result<31>;
1730                APSR.Z = IsZeroBit(result);
1731                APSR.C = carry;
1732                APSR.V = overflow;
1733    }
1734#endif
1735
1736    if (ConditionPassed(opcode))
1737    {
1738        bool success = false;
1739        const addr_t ip = ReadCoreReg (12, &success);
1740        if (!success)
1741            return false;
1742        uint32_t imm32;
1743        switch (encoding) {
1744        case eEncodingA1:
1745            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1746            break;
1747        default:
1748            return false;
1749        }
1750        addr_t ip_offset = imm32;
1751        addr_t addr = ip - ip_offset; // the adjusted ip value
1752
1753        EmulateInstruction::Context context;
1754        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1755        RegisterInfo dwarf_reg;
1756        GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1757        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1758
1759        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1760            return false;
1761    }
1762    return true;
1763}
1764
1765// Set ip to point to some stack offset.
1766// SUB (SP minus immediate)
1767bool
1768EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1769{
1770#if 0
1771    // ARM pseudo code...
1772    if (ConditionPassed())
1773    {
1774        EncodingSpecificOperations();
1775        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1776        if d == 15 then // Can only occur for ARM encoding
1777           ALUWritePC(result); // setflags is always FALSE here
1778        else
1779            R[d] = result;
1780            if setflags then
1781                APSR.N = result<31>;
1782                APSR.Z = IsZeroBit(result);
1783                APSR.C = carry;
1784                APSR.V = overflow;
1785    }
1786#endif
1787
1788    if (ConditionPassed(opcode))
1789    {
1790        bool success = false;
1791        const addr_t sp = ReadCoreReg (SP_REG, &success);
1792        if (!success)
1793            return false;
1794        uint32_t imm32;
1795        switch (encoding) {
1796        case eEncodingA1:
1797            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1798            break;
1799        default:
1800            return false;
1801        }
1802        addr_t sp_offset = imm32;
1803        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1804
1805        EmulateInstruction::Context context;
1806        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1807        RegisterInfo dwarf_reg;
1808        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1809        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1810
1811        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1812            return false;
1813    }
1814    return true;
1815}
1816
1817// This instruction subtracts an immediate value from the SP value, and writes
1818// the result to the destination register.
1819//
1820// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1821bool
1822EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1823{
1824#if 0
1825    // ARM pseudo code...
1826    if (ConditionPassed())
1827    {
1828        EncodingSpecificOperations();
1829        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1830        if d == 15 then        // Can only occur for ARM encoding
1831           ALUWritePC(result); // setflags is always FALSE here
1832        else
1833            R[d] = result;
1834            if setflags then
1835                APSR.N = result<31>;
1836                APSR.Z = IsZeroBit(result);
1837                APSR.C = carry;
1838                APSR.V = overflow;
1839    }
1840#endif
1841
1842    bool success = false;
1843    if (ConditionPassed(opcode))
1844    {
1845        const addr_t sp = ReadCoreReg (SP_REG, &success);
1846        if (!success)
1847            return false;
1848
1849        uint32_t Rd;
1850        bool setflags;
1851        uint32_t imm32;
1852        switch (encoding) {
1853        case eEncodingT1:
1854            Rd = 13;
1855            setflags = false;
1856            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1857            break;
1858        case eEncodingT2:
1859            Rd = Bits32(opcode, 11, 8);
1860            setflags = BitIsSet(opcode, 20);
1861            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1862            if (Rd == 15 && setflags)
1863                return EmulateCMPImm(opcode, eEncodingT2);
1864            if (Rd == 15 && !setflags)
1865                return false;
1866            break;
1867        case eEncodingT3:
1868            Rd = Bits32(opcode, 11, 8);
1869            setflags = false;
1870            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1871            if (Rd == 15)
1872                return false;
1873            break;
1874        case eEncodingA1:
1875            Rd = Bits32(opcode, 15, 12);
1876            setflags = BitIsSet(opcode, 20);
1877            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1878
1879            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1880            if (Rd == 15 && setflags)
1881                return EmulateSUBSPcLrEtc (opcode, encoding);
1882            break;
1883        default:
1884            return false;
1885        }
1886        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1887
1888        EmulateInstruction::Context context;
1889        if (Rd == 13)
1890        {
1891            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1892                                     // value gets passed down to context.SetImmediateSigned.
1893            context.type = EmulateInstruction::eContextAdjustStackPointer;
1894            context.SetImmediateSigned (-imm64); // the stack pointer offset
1895        }
1896        else
1897        {
1898            context.type = EmulateInstruction::eContextImmediate;
1899            context.SetNoArgs ();
1900        }
1901
1902        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1903            return false;
1904    }
1905    return true;
1906}
1907
1908// A store operation to the stack that also updates the SP.
1909bool
1910EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1911{
1912#if 0
1913    // ARM pseudo code...
1914    if (ConditionPassed())
1915    {
1916        EncodingSpecificOperations();
1917        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1918        address = if index then offset_addr else R[n];
1919        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1920        if wback then R[n] = offset_addr;
1921    }
1922#endif
1923
1924    bool conditional = false;
1925    bool success = false;
1926    if (ConditionPassed(opcode, &conditional))
1927    {
1928        const uint32_t addr_byte_size = GetAddressByteSize();
1929        const addr_t sp = ReadCoreReg (SP_REG, &success);
1930        if (!success)
1931            return false;
1932        uint32_t Rt; // the source register
1933        uint32_t imm12;
1934        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1935
1936        bool index;
1937        bool add;
1938        bool wback;
1939        switch (encoding) {
1940        case eEncodingA1:
1941            Rt = Bits32(opcode, 15, 12);
1942            imm12 = Bits32(opcode, 11, 0);
1943            Rn = Bits32 (opcode, 19, 16);
1944
1945            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1946                return false;
1947
1948            index = BitIsSet (opcode, 24);
1949            add = BitIsSet (opcode, 23);
1950            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1951
1952            if (wback && ((Rn == 15) || (Rn == Rt)))
1953                return false;
1954            break;
1955        default:
1956            return false;
1957        }
1958        addr_t offset_addr;
1959        if (add)
1960            offset_addr = sp + imm12;
1961        else
1962            offset_addr = sp - imm12;
1963
1964        addr_t addr;
1965        if (index)
1966            addr = offset_addr;
1967        else
1968            addr = sp;
1969
1970        EmulateInstruction::Context context;
1971        if (conditional)
1972            context.type = EmulateInstruction::eContextRegisterStore;
1973        else
1974            context.type = EmulateInstruction::eContextPushRegisterOnStack;
1975        RegisterInfo sp_reg;
1976        RegisterInfo dwarf_reg;
1977
1978        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1979        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1980        context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1981        if (Rt != 15)
1982        {
1983            uint32_t reg_value = ReadCoreReg(Rt, &success);
1984            if (!success)
1985                return false;
1986            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1987                return false;
1988        }
1989        else
1990        {
1991            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1992            if (!success)
1993                return false;
1994            if (!MemUWrite (context, addr, pc, addr_byte_size))
1995                return false;
1996        }
1997
1998
1999        if (wback)
2000        {
2001            context.type = EmulateInstruction::eContextAdjustStackPointer;
2002            context.SetImmediateSigned (addr - sp);
2003            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2004                return false;
2005        }
2006    }
2007    return true;
2008}
2009
2010// Vector Push stores multiple extension registers to the stack.
2011// It also updates SP to point to the start of the stored data.
2012bool
2013EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2014{
2015#if 0
2016    // ARM pseudo code...
2017    if (ConditionPassed())
2018    {
2019        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2020        address = SP - imm32;
2021        SP = SP - imm32;
2022        if single_regs then
2023            for r = 0 to regs-1
2024                MemA[address,4] = S[d+r]; address = address+4;
2025        else
2026            for r = 0 to regs-1
2027                // Store as two word-aligned words in the correct order for current endianness.
2028                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2029                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2030                address = address+8;
2031    }
2032#endif
2033
2034    bool success = false;
2035    bool conditional = false;
2036    if (ConditionPassed(opcode, &conditional))
2037    {
2038        const uint32_t addr_byte_size = GetAddressByteSize();
2039        const addr_t sp = ReadCoreReg (SP_REG, &success);
2040        if (!success)
2041            return false;
2042        bool single_regs;
2043        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2044        uint32_t imm32; // stack offset
2045        uint32_t regs;  // number of registers
2046        switch (encoding) {
2047        case eEncodingT1:
2048        case eEncodingA1:
2049            single_regs = false;
2050            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2051            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2052            // If UInt(imm8) is odd, see "FSTMX".
2053            regs = Bits32(opcode, 7, 0) / 2;
2054            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2055            if (regs == 0 || regs > 16 || (d + regs) > 32)
2056                return false;
2057            break;
2058        case eEncodingT2:
2059        case eEncodingA2:
2060            single_regs = true;
2061            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2062            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2063            regs = Bits32(opcode, 7, 0);
2064            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2065            if (regs == 0 || regs > 16 || (d + regs) > 32)
2066                return false;
2067            break;
2068        default:
2069            return false;
2070        }
2071        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2072        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2073        addr_t sp_offset = imm32;
2074        addr_t addr = sp - sp_offset;
2075        uint32_t i;
2076
2077        EmulateInstruction::Context context;
2078        if (conditional)
2079            context.type = EmulateInstruction::eContextRegisterStore;
2080        else
2081            context.type = EmulateInstruction::eContextPushRegisterOnStack;
2082        RegisterInfo dwarf_reg;
2083        RegisterInfo sp_reg;
2084        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2085        for (i=0; i<regs; ++i)
2086        {
2087            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2088            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2089            // uint64_t to accommodate 64-bit registers.
2090            uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2091            if (!success)
2092                return false;
2093            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2094                return false;
2095            addr += reg_byte_size;
2096        }
2097
2098        context.type = EmulateInstruction::eContextAdjustStackPointer;
2099        context.SetImmediateSigned (-sp_offset);
2100
2101        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2102            return false;
2103    }
2104    return true;
2105}
2106
2107// Vector Pop loads multiple extension registers from the stack.
2108// It also updates SP to point just above the loaded data.
2109bool
2110EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2111{
2112#if 0
2113    // ARM pseudo code...
2114    if (ConditionPassed())
2115    {
2116        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2117        address = SP;
2118        SP = SP + imm32;
2119        if single_regs then
2120            for r = 0 to regs-1
2121                S[d+r] = MemA[address,4]; address = address+4;
2122        else
2123            for r = 0 to regs-1
2124                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2125                // Combine the word-aligned words in the correct order for current endianness.
2126                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2127    }
2128#endif
2129
2130    bool success = false;
2131    bool conditional = false;
2132    if (ConditionPassed(opcode, &conditional))
2133    {
2134        const uint32_t addr_byte_size = GetAddressByteSize();
2135        const addr_t sp = ReadCoreReg (SP_REG, &success);
2136        if (!success)
2137            return false;
2138        bool single_regs;
2139        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2140        uint32_t imm32; // stack offset
2141        uint32_t regs;  // number of registers
2142        switch (encoding) {
2143        case eEncodingT1:
2144        case eEncodingA1:
2145            single_regs = false;
2146            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2147            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2148            // If UInt(imm8) is odd, see "FLDMX".
2149            regs = Bits32(opcode, 7, 0) / 2;
2150            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2151            if (regs == 0 || regs > 16 || (d + regs) > 32)
2152                return false;
2153            break;
2154        case eEncodingT2:
2155        case eEncodingA2:
2156            single_regs = true;
2157            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2158            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2159            regs = Bits32(opcode, 7, 0);
2160            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2161            if (regs == 0 || regs > 16 || (d + regs) > 32)
2162                return false;
2163            break;
2164        default:
2165            return false;
2166        }
2167        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2168        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2169        addr_t sp_offset = imm32;
2170        addr_t addr = sp;
2171        uint32_t i;
2172        uint64_t data; // uint64_t to accomodate 64-bit registers.
2173
2174        EmulateInstruction::Context context;
2175        if (conditional)
2176            context.type = EmulateInstruction::eContextRegisterLoad;
2177        else
2178            context.type = EmulateInstruction::eContextPopRegisterOffStack;
2179        RegisterInfo dwarf_reg;
2180        RegisterInfo sp_reg;
2181        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2182        for (i=0; i<regs; ++i)
2183        {
2184            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2185            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2186            data = MemARead(context, addr, reg_byte_size, 0, &success);
2187            if (!success)
2188                return false;
2189            if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2190                return false;
2191            addr += reg_byte_size;
2192        }
2193
2194        context.type = EmulateInstruction::eContextAdjustStackPointer;
2195        context.SetImmediateSigned (sp_offset);
2196
2197        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2198            return false;
2199    }
2200    return true;
2201}
2202
2203// SVC (previously SWI)
2204bool
2205EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2206{
2207#if 0
2208    // ARM pseudo code...
2209    if (ConditionPassed())
2210    {
2211        EncodingSpecificOperations();
2212        CallSupervisor();
2213    }
2214#endif
2215
2216    bool success = false;
2217
2218    if (ConditionPassed(opcode))
2219    {
2220        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2221        addr_t lr; // next instruction address
2222        if (!success)
2223            return false;
2224        uint32_t imm32; // the immediate constant
2225        uint32_t mode;  // ARM or Thumb mode
2226        switch (encoding) {
2227        case eEncodingT1:
2228            lr = (pc + 2) | 1u; // return address
2229            imm32 = Bits32(opcode, 7, 0);
2230            mode = eModeThumb;
2231            break;
2232        case eEncodingA1:
2233            lr = pc + 4; // return address
2234            imm32 = Bits32(opcode, 23, 0);
2235            mode = eModeARM;
2236            break;
2237        default:
2238            return false;
2239        }
2240
2241        EmulateInstruction::Context context;
2242        context.type = EmulateInstruction::eContextSupervisorCall;
2243        context.SetISAAndImmediate (mode, imm32);
2244        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2245            return false;
2246    }
2247    return true;
2248}
2249
2250// If Then makes up to four following instructions (the IT block) conditional.
2251bool
2252EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2253{
2254#if 0
2255    // ARM pseudo code...
2256    EncodingSpecificOperations();
2257    ITSTATE.IT<7:0> = firstcond:mask;
2258#endif
2259
2260    m_it_session.InitIT(Bits32(opcode, 7, 0));
2261    return true;
2262}
2263
2264bool
2265EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2266{
2267    // NOP, nothing to do...
2268    return true;
2269}
2270
2271// Branch causes a branch to a target address.
2272bool
2273EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2274{
2275#if 0
2276    // ARM pseudo code...
2277    if (ConditionPassed())
2278    {
2279        EncodingSpecificOperations();
2280        BranchWritePC(PC + imm32);
2281    }
2282#endif
2283
2284    bool success = false;
2285
2286    if (ConditionPassed(opcode))
2287    {
2288        EmulateInstruction::Context context;
2289        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2290        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2291        if (!success)
2292            return false;
2293        addr_t target; // target address
2294        int32_t imm32; // PC-relative offset
2295        switch (encoding) {
2296        case eEncodingT1:
2297            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2298            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2299            target = pc + imm32;
2300            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2301            break;
2302        case eEncodingT2:
2303            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2304            target = pc + imm32;
2305            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2306            break;
2307        case eEncodingT3:
2308            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2309            {
2310            uint32_t S = Bit32(opcode, 26);
2311            uint32_t imm6 = Bits32(opcode, 21, 16);
2312            uint32_t J1 = Bit32(opcode, 13);
2313            uint32_t J2 = Bit32(opcode, 11);
2314            uint32_t imm11 = Bits32(opcode, 10, 0);
2315            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2316            imm32 = llvm::SignExtend32<21>(imm21);
2317            target = pc + imm32;
2318            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2319            break;
2320            }
2321        case eEncodingT4:
2322            {
2323            uint32_t S = Bit32(opcode, 26);
2324            uint32_t imm10 = Bits32(opcode, 25, 16);
2325            uint32_t J1 = Bit32(opcode, 13);
2326            uint32_t J2 = Bit32(opcode, 11);
2327            uint32_t imm11 = Bits32(opcode, 10, 0);
2328            uint32_t I1 = !(J1 ^ S);
2329            uint32_t I2 = !(J2 ^ S);
2330            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2331            imm32 = llvm::SignExtend32<25>(imm25);
2332            target = pc + imm32;
2333            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2334            break;
2335            }
2336        case eEncodingA1:
2337            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2338            target = pc + imm32;
2339            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2340            break;
2341        default:
2342            return false;
2343        }
2344        if (!BranchWritePC(context, target))
2345            return false;
2346    }
2347    return true;
2348}
2349
2350// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2351// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2352// CBNZ, CBZ
2353bool
2354EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2355{
2356#if 0
2357    // ARM pseudo code...
2358    EncodingSpecificOperations();
2359    if nonzero ^ IsZero(R[n]) then
2360        BranchWritePC(PC + imm32);
2361#endif
2362
2363    bool success = false;
2364
2365    // Read the register value from the operand register Rn.
2366    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2367    if (!success)
2368        return false;
2369
2370    EmulateInstruction::Context context;
2371    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2372    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2373    if (!success)
2374        return false;
2375
2376    addr_t target;  // target address
2377    uint32_t imm32; // PC-relative offset to branch forward
2378    bool nonzero;
2379    switch (encoding) {
2380    case eEncodingT1:
2381        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2382        nonzero = BitIsSet(opcode, 11);
2383        target = pc + imm32;
2384        context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2385        break;
2386    default:
2387        return false;
2388    }
2389    if (nonzero ^ (reg_val == 0))
2390        if (!BranchWritePC(context, target))
2391            return false;
2392
2393    return true;
2394}
2395
2396// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2397// A base register provides a pointer to the table, and a second register supplies an index into the table.
2398// The branch length is twice the value of the byte returned from the table.
2399//
2400// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2401// A base register provides a pointer to the table, and a second register supplies an index into the table.
2402// The branch length is twice the value of the halfword returned from the table.
2403// TBB, TBH
2404bool
2405EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2406{
2407#if 0
2408    // ARM pseudo code...
2409    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2410    if is_tbh then
2411        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2412    else
2413        halfwords = UInt(MemU[R[n]+R[m], 1]);
2414    BranchWritePC(PC + 2*halfwords);
2415#endif
2416
2417    bool success = false;
2418
2419    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2420    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2421    bool is_tbh;     // true if table branch halfword
2422    switch (encoding) {
2423    case eEncodingT1:
2424        Rn = Bits32(opcode, 19, 16);
2425        Rm = Bits32(opcode, 3, 0);
2426        is_tbh = BitIsSet(opcode, 4);
2427        if (Rn == 13 || BadReg(Rm))
2428            return false;
2429        if (InITBlock() && !LastInITBlock())
2430            return false;
2431        break;
2432    default:
2433        return false;
2434    }
2435
2436    // Read the address of the table from the operand register Rn.
2437    // The PC can be used, in which case the table immediately follows this instruction.
2438    uint32_t base = ReadCoreReg(Rm, &success);
2439    if (!success)
2440        return false;
2441
2442    // the table index
2443    uint32_t index = ReadCoreReg(Rm, &success);
2444    if (!success)
2445        return false;
2446
2447    // the offsetted table address
2448    addr_t addr = base + (is_tbh ? index*2 : index);
2449
2450    // PC-relative offset to branch forward
2451    EmulateInstruction::Context context;
2452    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2453    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2454    if (!success)
2455        return false;
2456
2457    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2458    if (!success)
2459        return false;
2460
2461    // target address
2462    addr_t target = pc + offset;
2463    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2464    context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2465
2466    if (!BranchWritePC(context, target))
2467        return false;
2468
2469    return true;
2470}
2471
2472// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2473// It can optionally update the condition flags based on the result.
2474bool
2475EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2476{
2477#if 0
2478    if ConditionPassed() then
2479        EncodingSpecificOperations();
2480        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2481        R[d] = result;
2482        if setflags then
2483            APSR.N = result<31>;
2484            APSR.Z = IsZeroBit(result);
2485            APSR.C = carry;
2486            APSR.V = overflow;
2487#endif
2488
2489    bool success = false;
2490
2491    if (ConditionPassed(opcode))
2492    {
2493        uint32_t d;
2494        uint32_t n;
2495        bool setflags;
2496        uint32_t imm32;
2497        uint32_t carry_out;
2498
2499        //EncodingSpecificOperations();
2500        switch (encoding)
2501        {
2502            case eEncodingT1:
2503                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2504                d = Bits32 (opcode, 2, 0);
2505                n = Bits32 (opcode, 5, 3);
2506                setflags = !InITBlock();
2507                imm32 = Bits32 (opcode, 8,6);
2508
2509                break;
2510
2511            case eEncodingT2:
2512                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2513                d = Bits32 (opcode, 10, 8);
2514                n = Bits32 (opcode, 10, 8);
2515                setflags = !InITBlock();
2516                imm32 = Bits32 (opcode, 7, 0);
2517
2518                break;
2519
2520            case eEncodingT3:
2521                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2522                // if Rn == '1101' then SEE ADD (SP plus immediate);
2523                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2524                d = Bits32 (opcode, 11, 8);
2525                n = Bits32 (opcode, 19, 16);
2526                setflags = BitIsSet (opcode, 20);
2527                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2528
2529                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2530                if (BadReg (d) || (n == 15))
2531                    return false;
2532
2533                break;
2534
2535            case eEncodingT4:
2536            {
2537                // if Rn == '1111' then SEE ADR;
2538                // if Rn == '1101' then SEE ADD (SP plus immediate);
2539                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2540                d = Bits32 (opcode, 11, 8);
2541                n = Bits32 (opcode, 19, 16);
2542                setflags = false;
2543                uint32_t i = Bit32 (opcode, 26);
2544                uint32_t imm3 = Bits32 (opcode, 14, 12);
2545                uint32_t imm8 = Bits32 (opcode, 7, 0);
2546                imm32 = (i << 11) | (imm3 << 8) | imm8;
2547
2548                // if BadReg(d) then UNPREDICTABLE;
2549                if (BadReg (d))
2550                    return false;
2551
2552                break;
2553            }
2554            default:
2555                return false;
2556        }
2557
2558        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2559        if (!success)
2560            return false;
2561
2562        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2563        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2564
2565        RegisterInfo reg_n;
2566        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2567
2568        EmulateInstruction::Context context;
2569        context.type = eContextArithmetic;
2570        context.SetRegisterPlusOffset (reg_n, imm32);
2571
2572        //R[d] = result;
2573        //if setflags then
2574            //APSR.N = result<31>;
2575            //APSR.Z = IsZeroBit(result);
2576            //APSR.C = carry;
2577            //APSR.V = overflow;
2578        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2579            return false;
2580
2581    }
2582    return true;
2583}
2584
2585// This instruction adds an immediate value to a register value, and writes the result to the destination
2586// register.  It can optionally update the condition flags based on the result.
2587bool
2588EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2589{
2590#if 0
2591    // ARM pseudo code...
2592    if ConditionPassed() then
2593        EncodingSpecificOperations();
2594        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2595        if d == 15 then
2596            ALUWritePC(result); // setflags is always FALSE here
2597        else
2598            R[d] = result;
2599            if setflags then
2600                APSR.N = result<31>;
2601                APSR.Z = IsZeroBit(result);
2602                APSR.C = carry;
2603                APSR.V = overflow;
2604#endif
2605
2606    bool success = false;
2607
2608    if (ConditionPassed(opcode))
2609    {
2610        uint32_t Rd, Rn;
2611        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2612        bool setflags;
2613        switch (encoding)
2614        {
2615        case eEncodingA1:
2616            Rd = Bits32(opcode, 15, 12);
2617            Rn = Bits32(opcode, 19, 16);
2618            setflags = BitIsSet(opcode, 20);
2619            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2620            break;
2621        default:
2622            return false;
2623        }
2624
2625        // Read the first operand.
2626        uint32_t val1 = ReadCoreReg(Rn, &success);
2627        if (!success)
2628            return false;
2629
2630        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2631
2632        EmulateInstruction::Context context;
2633        context.type = eContextArithmetic;
2634        RegisterInfo dwarf_reg;
2635        GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2636        context.SetRegisterPlusOffset (dwarf_reg, imm32);
2637
2638        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2639            return false;
2640    }
2641    return true;
2642}
2643
2644// This instruction adds a register value and an optionally-shifted register value, and writes the result
2645// to the destination register. It can optionally update the condition flags based on the result.
2646bool
2647EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2648{
2649#if 0
2650    // ARM pseudo code...
2651    if ConditionPassed() then
2652        EncodingSpecificOperations();
2653        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2654        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2655        if d == 15 then
2656            ALUWritePC(result); // setflags is always FALSE here
2657        else
2658            R[d] = result;
2659            if setflags then
2660                APSR.N = result<31>;
2661                APSR.Z = IsZeroBit(result);
2662                APSR.C = carry;
2663                APSR.V = overflow;
2664#endif
2665
2666    bool success = false;
2667
2668    if (ConditionPassed(opcode))
2669    {
2670        uint32_t Rd, Rn, Rm;
2671        ARM_ShifterType shift_t;
2672        uint32_t shift_n; // the shift applied to the value read from Rm
2673        bool setflags;
2674        switch (encoding)
2675        {
2676        case eEncodingT1:
2677            Rd = Bits32(opcode, 2, 0);
2678            Rn = Bits32(opcode, 5, 3);
2679            Rm = Bits32(opcode, 8, 6);
2680            setflags = !InITBlock();
2681            shift_t = SRType_LSL;
2682            shift_n = 0;
2683            break;
2684        case eEncodingT2:
2685            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2686            Rm = Bits32(opcode, 6, 3);
2687            setflags = false;
2688            shift_t = SRType_LSL;
2689            shift_n = 0;
2690            if (Rn == 15 && Rm == 15)
2691                return false;
2692            if (Rd == 15 && InITBlock() && !LastInITBlock())
2693                return false;
2694            break;
2695        case eEncodingA1:
2696            Rd = Bits32(opcode, 15, 12);
2697            Rn = Bits32(opcode, 19, 16);
2698            Rm = Bits32(opcode, 3, 0);
2699            setflags = BitIsSet(opcode, 20);
2700            shift_n = DecodeImmShiftARM(opcode, shift_t);
2701            break;
2702        default:
2703            return false;
2704        }
2705
2706        // Read the first operand.
2707        uint32_t val1 = ReadCoreReg(Rn, &success);
2708        if (!success)
2709            return false;
2710
2711        // Read the second operand.
2712        uint32_t val2 = ReadCoreReg(Rm, &success);
2713        if (!success)
2714            return false;
2715
2716        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2717        if (!success)
2718            return false;
2719        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2720
2721        EmulateInstruction::Context context;
2722        context.type = eContextArithmetic;
2723        RegisterInfo op1_reg;
2724        RegisterInfo op2_reg;
2725        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2726        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2727        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2728
2729        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2730            return false;
2731    }
2732    return true;
2733}
2734
2735// Compare Negative (immediate) adds a register value and an immediate value.
2736// It updates the condition flags based on the result, and discards the result.
2737bool
2738EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2739{
2740#if 0
2741    // ARM pseudo code...
2742    if ConditionPassed() then
2743        EncodingSpecificOperations();
2744        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2745        APSR.N = result<31>;
2746        APSR.Z = IsZeroBit(result);
2747        APSR.C = carry;
2748        APSR.V = overflow;
2749#endif
2750
2751    bool success = false;
2752
2753    uint32_t Rn; // the first operand
2754    uint32_t imm32; // the immediate value to be compared with
2755    switch (encoding) {
2756    case eEncodingT1:
2757        Rn = Bits32(opcode, 19, 16);
2758        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2759        if (Rn == 15)
2760            return false;
2761        break;
2762    case eEncodingA1:
2763        Rn = Bits32(opcode, 19, 16);
2764        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2765        break;
2766    default:
2767        return false;
2768    }
2769    // Read the register value from the operand register Rn.
2770    uint32_t reg_val = ReadCoreReg(Rn, &success);
2771    if (!success)
2772        return false;
2773
2774    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2775
2776    EmulateInstruction::Context context;
2777    context.type = EmulateInstruction::eContextImmediate;
2778    context.SetNoArgs ();
2779    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2780        return false;
2781
2782    return true;
2783}
2784
2785// Compare Negative (register) adds a register value and an optionally-shifted register value.
2786// It updates the condition flags based on the result, and discards the result.
2787bool
2788EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2789{
2790#if 0
2791    // ARM pseudo code...
2792    if ConditionPassed() then
2793        EncodingSpecificOperations();
2794        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2795        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2796        APSR.N = result<31>;
2797        APSR.Z = IsZeroBit(result);
2798        APSR.C = carry;
2799        APSR.V = overflow;
2800#endif
2801
2802    bool success = false;
2803
2804    uint32_t Rn; // the first operand
2805    uint32_t Rm; // the second operand
2806    ARM_ShifterType shift_t;
2807    uint32_t shift_n; // the shift applied to the value read from Rm
2808    switch (encoding) {
2809    case eEncodingT1:
2810        Rn = Bits32(opcode, 2, 0);
2811        Rm = Bits32(opcode, 5, 3);
2812        shift_t = SRType_LSL;
2813        shift_n = 0;
2814        break;
2815    case eEncodingT2:
2816        Rn = Bits32(opcode, 19, 16);
2817        Rm = Bits32(opcode, 3, 0);
2818        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2819        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2820        if (Rn == 15 || BadReg(Rm))
2821            return false;
2822        break;
2823    case eEncodingA1:
2824        Rn = Bits32(opcode, 19, 16);
2825        Rm = Bits32(opcode, 3, 0);
2826        shift_n = DecodeImmShiftARM(opcode, shift_t);
2827        break;
2828    default:
2829        return false;
2830    }
2831    // Read the register value from register Rn.
2832    uint32_t val1 = ReadCoreReg(Rn, &success);
2833    if (!success)
2834        return false;
2835
2836    // Read the register value from register Rm.
2837    uint32_t val2 = ReadCoreReg(Rm, &success);
2838    if (!success)
2839        return false;
2840
2841    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2842    if (!success)
2843        return false;
2844    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2845
2846    EmulateInstruction::Context context;
2847    context.type = EmulateInstruction::eContextImmediate;
2848    context.SetNoArgs();
2849    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2850        return false;
2851
2852    return true;
2853}
2854
2855// Compare (immediate) subtracts an immediate value from a register value.
2856// It updates the condition flags based on the result, and discards the result.
2857bool
2858EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2859{
2860#if 0
2861    // ARM pseudo code...
2862    if ConditionPassed() then
2863        EncodingSpecificOperations();
2864        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2865        APSR.N = result<31>;
2866        APSR.Z = IsZeroBit(result);
2867        APSR.C = carry;
2868        APSR.V = overflow;
2869#endif
2870
2871    bool success = false;
2872
2873    uint32_t Rn; // the first operand
2874    uint32_t imm32; // the immediate value to be compared with
2875    switch (encoding) {
2876    case eEncodingT1:
2877        Rn = Bits32(opcode, 10, 8);
2878        imm32 = Bits32(opcode, 7, 0);
2879        break;
2880    case eEncodingT2:
2881        Rn = Bits32(opcode, 19, 16);
2882        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2883        if (Rn == 15)
2884            return false;
2885        break;
2886    case eEncodingA1:
2887        Rn = Bits32(opcode, 19, 16);
2888        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2889        break;
2890    default:
2891        return false;
2892    }
2893    // Read the register value from the operand register Rn.
2894    uint32_t reg_val = ReadCoreReg(Rn, &success);
2895    if (!success)
2896        return false;
2897
2898    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2899
2900    EmulateInstruction::Context context;
2901    context.type = EmulateInstruction::eContextImmediate;
2902    context.SetNoArgs ();
2903    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2904        return false;
2905
2906    return true;
2907}
2908
2909// Compare (register) subtracts an optionally-shifted register value from a register value.
2910// It updates the condition flags based on the result, and discards the result.
2911bool
2912EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2913{
2914#if 0
2915    // ARM pseudo code...
2916    if ConditionPassed() then
2917        EncodingSpecificOperations();
2918        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2919        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2920        APSR.N = result<31>;
2921        APSR.Z = IsZeroBit(result);
2922        APSR.C = carry;
2923        APSR.V = overflow;
2924#endif
2925
2926    bool success = false;
2927
2928    uint32_t Rn; // the first operand
2929    uint32_t Rm; // the second operand
2930    ARM_ShifterType shift_t;
2931    uint32_t shift_n; // the shift applied to the value read from Rm
2932    switch (encoding) {
2933    case eEncodingT1:
2934        Rn = Bits32(opcode, 2, 0);
2935        Rm = Bits32(opcode, 5, 3);
2936        shift_t = SRType_LSL;
2937        shift_n = 0;
2938        break;
2939    case eEncodingT2:
2940        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2941        Rm = Bits32(opcode, 6, 3);
2942        shift_t = SRType_LSL;
2943        shift_n = 0;
2944        if (Rn < 8 && Rm < 8)
2945            return false;
2946        if (Rn == 15 || Rm == 15)
2947            return false;
2948        break;
2949    case eEncodingA1:
2950        Rn = Bits32(opcode, 19, 16);
2951        Rm = Bits32(opcode, 3, 0);
2952        shift_n = DecodeImmShiftARM(opcode, shift_t);
2953        break;
2954    default:
2955        return false;
2956    }
2957    // Read the register value from register Rn.
2958    uint32_t val1 = ReadCoreReg(Rn, &success);
2959    if (!success)
2960        return false;
2961
2962    // Read the register value from register Rm.
2963    uint32_t val2 = ReadCoreReg(Rm, &success);
2964    if (!success)
2965        return false;
2966
2967    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2968    if (!success)
2969        return false;
2970    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2971
2972    EmulateInstruction::Context context;
2973    context.type = EmulateInstruction::eContextImmediate;
2974    context.SetNoArgs();
2975    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2976        return false;
2977
2978    return true;
2979}
2980
2981// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2982// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2983// optionally update the condition flags based on the result.
2984bool
2985EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2986{
2987#if 0
2988    // ARM pseudo code...
2989    if ConditionPassed() then
2990        EncodingSpecificOperations();
2991        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2992        if d == 15 then         // Can only occur for ARM encoding
2993            ALUWritePC(result); // setflags is always FALSE here
2994        else
2995            R[d] = result;
2996            if setflags then
2997                APSR.N = result<31>;
2998                APSR.Z = IsZeroBit(result);
2999                APSR.C = carry;
3000                // APSR.V unchanged
3001#endif
3002
3003    return EmulateShiftImm (opcode, encoding, SRType_ASR);
3004}
3005
3006// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3007// shifting in copies of its sign bit, and writes the result to the destination register.
3008// The variable number of bits is read from the bottom byte of a register. It can optionally update
3009// the condition flags based on the result.
3010bool
3011EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3012{
3013#if 0
3014    // ARM pseudo code...
3015    if ConditionPassed() then
3016        EncodingSpecificOperations();
3017        shift_n = UInt(R[m]<7:0>);
3018        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3019        R[d] = result;
3020        if setflags then
3021            APSR.N = result<31>;
3022            APSR.Z = IsZeroBit(result);
3023            APSR.C = carry;
3024            // APSR.V unchanged
3025#endif
3026
3027    return EmulateShiftReg (opcode, encoding, SRType_ASR);
3028}
3029
3030// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3031// shifting in zeros, and writes the result to the destination register.  It can optionally
3032// update the condition flags based on the result.
3033bool
3034EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3035{
3036#if 0
3037    // ARM pseudo code...
3038    if ConditionPassed() then
3039        EncodingSpecificOperations();
3040        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3041        if d == 15 then         // Can only occur for ARM encoding
3042            ALUWritePC(result); // setflags is always FALSE here
3043        else
3044            R[d] = result;
3045            if setflags then
3046                APSR.N = result<31>;
3047                APSR.Z = IsZeroBit(result);
3048                APSR.C = carry;
3049                // APSR.V unchanged
3050#endif
3051
3052    return EmulateShiftImm (opcode, encoding, SRType_LSL);
3053}
3054
3055// Logical Shift Left (register) shifts a register value left by a variable number of bits,
3056// shifting in zeros, and writes the result to the destination register.  The variable number
3057// of bits is read from the bottom byte of a register. It can optionally update the condition
3058// flags based on the result.
3059bool
3060EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3061{
3062#if 0
3063    // ARM pseudo code...
3064    if ConditionPassed() then
3065        EncodingSpecificOperations();
3066        shift_n = UInt(R[m]<7:0>);
3067        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3068        R[d] = result;
3069        if setflags then
3070            APSR.N = result<31>;
3071            APSR.Z = IsZeroBit(result);
3072            APSR.C = carry;
3073            // APSR.V unchanged
3074#endif
3075
3076    return EmulateShiftReg (opcode, encoding, SRType_LSL);
3077}
3078
3079// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3080// shifting in zeros, and writes the result to the destination register.  It can optionally
3081// update the condition flags based on the result.
3082bool
3083EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3084{
3085#if 0
3086    // ARM pseudo code...
3087    if ConditionPassed() then
3088        EncodingSpecificOperations();
3089        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3090        if d == 15 then         // Can only occur for ARM encoding
3091            ALUWritePC(result); // setflags is always FALSE here
3092        else
3093            R[d] = result;
3094            if setflags then
3095                APSR.N = result<31>;
3096                APSR.Z = IsZeroBit(result);
3097                APSR.C = carry;
3098                // APSR.V unchanged
3099#endif
3100
3101    return EmulateShiftImm (opcode, encoding, SRType_LSR);
3102}
3103
3104// Logical Shift Right (register) shifts a register value right by a variable number of bits,
3105// shifting in zeros, and writes the result to the destination register.  The variable number
3106// of bits is read from the bottom byte of a register. It can optionally update the condition
3107// flags based on the result.
3108bool
3109EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3110{
3111#if 0
3112    // ARM pseudo code...
3113    if ConditionPassed() then
3114        EncodingSpecificOperations();
3115        shift_n = UInt(R[m]<7:0>);
3116        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3117        R[d] = result;
3118        if setflags then
3119            APSR.N = result<31>;
3120            APSR.Z = IsZeroBit(result);
3121            APSR.C = carry;
3122            // APSR.V unchanged
3123#endif
3124
3125    return EmulateShiftReg (opcode, encoding, SRType_LSR);
3126}
3127
3128// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3129// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3130// It can optionally update the condition flags based on the result.
3131bool
3132EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3133{
3134#if 0
3135    // ARM pseudo code...
3136    if ConditionPassed() then
3137        EncodingSpecificOperations();
3138        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3139        if d == 15 then         // Can only occur for ARM encoding
3140            ALUWritePC(result); // setflags is always FALSE here
3141        else
3142            R[d] = result;
3143            if setflags then
3144                APSR.N = result<31>;
3145                APSR.Z = IsZeroBit(result);
3146                APSR.C = carry;
3147                // APSR.V unchanged
3148#endif
3149
3150    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3151}
3152
3153// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3154// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3155// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3156// flags based on the result.
3157bool
3158EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3159{
3160#if 0
3161    // ARM pseudo code...
3162    if ConditionPassed() then
3163        EncodingSpecificOperations();
3164        shift_n = UInt(R[m]<7:0>);
3165        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3166        R[d] = result;
3167        if setflags then
3168            APSR.N = result<31>;
3169            APSR.Z = IsZeroBit(result);
3170            APSR.C = carry;
3171            // APSR.V unchanged
3172#endif
3173
3174    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3175}
3176
3177// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3178// with the carry flag shifted into bit [31].
3179//
3180// RRX can optionally update the condition flags based on the result.
3181// In that case, bit [0] is shifted into the carry flag.
3182bool
3183EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3184{
3185#if 0
3186    // ARM pseudo code...
3187    if ConditionPassed() then
3188        EncodingSpecificOperations();
3189        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3190        if d == 15 then         // Can only occur for ARM encoding
3191            ALUWritePC(result); // setflags is always FALSE here
3192        else
3193            R[d] = result;
3194            if setflags then
3195                APSR.N = result<31>;
3196                APSR.Z = IsZeroBit(result);
3197                APSR.C = carry;
3198                // APSR.V unchanged
3199#endif
3200
3201    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3202}
3203
3204bool
3205EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3206{
3207//    assert(shift_type == SRType_ASR
3208//           || shift_type == SRType_LSL
3209//           || shift_type == SRType_LSR
3210//           || shift_type == SRType_ROR
3211//           || shift_type == SRType_RRX);
3212
3213    bool success = false;
3214
3215    if (ConditionPassed(opcode))
3216    {
3217        uint32_t Rd;    // the destination register
3218        uint32_t Rm;    // the first operand register
3219        uint32_t imm5;  // encoding for the shift amount
3220        uint32_t carry; // the carry bit after the shift operation
3221        bool setflags;
3222
3223        // Special case handling!
3224        // A8.6.139 ROR (immediate) -- Encoding T1
3225        ARMEncoding use_encoding = encoding;
3226        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3227        {
3228            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3229            // have the same decoding of bit fields as the other Thumb2 shift operations.
3230            use_encoding = eEncodingT2;
3231        }
3232
3233        switch (use_encoding) {
3234        case eEncodingT1:
3235            // Due to the above special case handling!
3236            if (shift_type == SRType_ROR)
3237                return false;
3238
3239            Rd = Bits32(opcode, 2, 0);
3240            Rm = Bits32(opcode, 5, 3);
3241            setflags = !InITBlock();
3242            imm5 = Bits32(opcode, 10, 6);
3243            break;
3244        case eEncodingT2:
3245            // A8.6.141 RRX
3246            // There's no imm form of RRX instructions.
3247            if (shift_type == SRType_RRX)
3248                return false;
3249
3250            Rd = Bits32(opcode, 11, 8);
3251            Rm = Bits32(opcode, 3, 0);
3252            setflags = BitIsSet(opcode, 20);
3253            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3254            if (BadReg(Rd) || BadReg(Rm))
3255                return false;
3256            break;
3257        case eEncodingA1:
3258            Rd = Bits32(opcode, 15, 12);
3259            Rm = Bits32(opcode, 3, 0);
3260            setflags = BitIsSet(opcode, 20);
3261            imm5 = Bits32(opcode, 11, 7);
3262            break;
3263        default:
3264            return false;
3265        }
3266
3267        // A8.6.139 ROR (immediate)
3268        if (shift_type == SRType_ROR && imm5 == 0)
3269            shift_type = SRType_RRX;
3270
3271        // Get the first operand.
3272        uint32_t value = ReadCoreReg (Rm, &success);
3273        if (!success)
3274            return false;
3275
3276        // Decode the shift amount if not RRX.
3277        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3278
3279        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3280        if (!success)
3281            return false;
3282
3283        // The context specifies that an immediate is to be moved into Rd.
3284        EmulateInstruction::Context context;
3285        context.type = EmulateInstruction::eContextImmediate;
3286        context.SetNoArgs ();
3287
3288        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3289            return false;
3290    }
3291    return true;
3292}
3293
3294bool
3295EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3296{
3297    // assert(shift_type == SRType_ASR
3298    //        || shift_type == SRType_LSL
3299    //        || shift_type == SRType_LSR
3300    //        || shift_type == SRType_ROR);
3301
3302    bool success = false;
3303
3304    if (ConditionPassed(opcode))
3305    {
3306        uint32_t Rd;    // the destination register
3307        uint32_t Rn;    // the first operand register
3308        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3309        uint32_t carry; // the carry bit after the shift operation
3310        bool setflags;
3311        switch (encoding) {
3312        case eEncodingT1:
3313            Rd = Bits32(opcode, 2, 0);
3314            Rn = Rd;
3315            Rm = Bits32(opcode, 5, 3);
3316            setflags = !InITBlock();
3317            break;
3318        case eEncodingT2:
3319            Rd = Bits32(opcode, 11, 8);
3320            Rn = Bits32(opcode, 19, 16);
3321            Rm = Bits32(opcode, 3, 0);
3322            setflags = BitIsSet(opcode, 20);
3323            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3324                return false;
3325            break;
3326        case eEncodingA1:
3327            Rd = Bits32(opcode, 15, 12);
3328            Rn = Bits32(opcode, 3, 0);
3329            Rm = Bits32(opcode, 11, 8);
3330            setflags = BitIsSet(opcode, 20);
3331            if (Rd == 15 || Rn == 15 || Rm == 15)
3332                return false;
3333            break;
3334        default:
3335            return false;
3336        }
3337
3338        // Get the first operand.
3339        uint32_t value = ReadCoreReg (Rn, &success);
3340        if (!success)
3341            return false;
3342        // Get the Rm register content.
3343        uint32_t val = ReadCoreReg (Rm, &success);
3344        if (!success)
3345            return false;
3346
3347        // Get the shift amount.
3348        uint32_t amt = Bits32(val, 7, 0);
3349
3350        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3351        if (!success)
3352            return false;
3353
3354        // The context specifies that an immediate is to be moved into Rd.
3355        EmulateInstruction::Context context;
3356        context.type = EmulateInstruction::eContextImmediate;
3357        context.SetNoArgs ();
3358
3359        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3360            return false;
3361    }
3362    return true;
3363}
3364
3365// LDM loads multiple registers from consecutive memory locations, using an
3366// address from a base register.  Optionally the address just above the highest of those locations
3367// can be written back to the base register.
3368bool
3369EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3370{
3371#if 0
3372    // ARM pseudo code...
3373    if ConditionPassed()
3374        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3375        address = R[n];
3376
3377        for i = 0 to 14
3378            if registers<i> == '1' then
3379                R[i] = MemA[address, 4]; address = address + 4;
3380        if registers<15> == '1' then
3381            LoadWritePC (MemA[address, 4]);
3382
3383        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3384        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3385
3386#endif
3387
3388    bool success = false;
3389    bool conditional = false;
3390    if (ConditionPassed(opcode, &conditional))
3391    {
3392        uint32_t n;
3393        uint32_t registers = 0;
3394        bool wback;
3395        const uint32_t addr_byte_size = GetAddressByteSize();
3396        switch (encoding)
3397        {
3398            case eEncodingT1:
3399                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3400                n = Bits32 (opcode, 10, 8);
3401                registers = Bits32 (opcode, 7, 0);
3402                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3403                wback = BitIsClear (registers, n);
3404                // if BitCount(registers) < 1 then UNPREDICTABLE;
3405                if (BitCount(registers) < 1)
3406                    return false;
3407                break;
3408            case eEncodingT2:
3409                // if W == '1' && Rn == '1101' then SEE POP;
3410                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3411                n = Bits32 (opcode, 19, 16);
3412                registers = Bits32 (opcode, 15, 0);
3413                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3414                wback = BitIsSet (opcode, 21);
3415
3416                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3417                if ((n == 15)
3418                    || (BitCount (registers) < 2)
3419                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3420                    return false;
3421
3422                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3423                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3424                    return false;
3425
3426                // if wback && registers<n> == '1' then UNPREDICTABLE;
3427                if (wback
3428                    && BitIsSet (registers, n))
3429                    return false;
3430                break;
3431
3432            case eEncodingA1:
3433                n = Bits32 (opcode, 19, 16);
3434                registers = Bits32 (opcode, 15, 0);
3435                wback = BitIsSet (opcode, 21);
3436                if ((n == 15)
3437                    || (BitCount (registers) < 1))
3438                    return false;
3439                break;
3440            default:
3441                return false;
3442        }
3443
3444        int32_t offset = 0;
3445        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3446        if (!success)
3447            return false;
3448
3449        EmulateInstruction::Context context;
3450        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3451        RegisterInfo dwarf_reg;
3452        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3453        context.SetRegisterPlusOffset (dwarf_reg, offset);
3454
3455        for (int i = 0; i < 14; ++i)
3456        {
3457            if (BitIsSet (registers, i))
3458            {
3459                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3460                context.SetRegisterPlusOffset (dwarf_reg, offset);
3461                if (wback && (n == 13)) // Pop Instruction
3462                {
3463                    if (conditional)
3464                        context.type = EmulateInstruction::eContextRegisterLoad;
3465                    else
3466                        context.type = EmulateInstruction::eContextPopRegisterOffStack;
3467                }
3468
3469                // R[i] = MemA [address, 4]; address = address + 4;
3470                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3471                if (!success)
3472                    return false;
3473
3474                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3475                    return false;
3476
3477                offset += addr_byte_size;
3478            }
3479        }
3480
3481        if (BitIsSet (registers, 15))
3482        {
3483            //LoadWritePC (MemA [address, 4]);
3484            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3485            context.SetRegisterPlusOffset (dwarf_reg, offset);
3486            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3487            if (!success)
3488                return false;
3489            // In ARMv5T and above, this is an interworking branch.
3490            if (!LoadWritePC(context, data))
3491                return false;
3492        }
3493
3494        if (wback && BitIsClear (registers, n))
3495        {
3496            // R[n] = R[n] + 4 * BitCount (registers)
3497            int32_t offset = addr_byte_size * BitCount (registers);
3498            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3499            context.SetRegisterPlusOffset (dwarf_reg, offset);
3500
3501            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3502                return false;
3503        }
3504        if (wback && BitIsSet (registers, n))
3505            // R[n] bits(32) UNKNOWN;
3506            return WriteBits32Unknown (n);
3507    }
3508    return true;
3509}
3510
3511// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3512// The consecutive memory locations end at this address and the address just below the lowest of those locations
3513// can optionally be written back to the base register.
3514bool
3515EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3516{
3517#if 0
3518    // ARM pseudo code...
3519    if ConditionPassed() then
3520        EncodingSpecificOperations();
3521        address = R[n] - 4*BitCount(registers) + 4;
3522
3523        for i = 0 to 14
3524            if registers<i> == '1' then
3525                  R[i] = MemA[address,4]; address = address + 4;
3526
3527        if registers<15> == '1' then
3528            LoadWritePC(MemA[address,4]);
3529
3530        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3531        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3532#endif
3533
3534    bool success = false;
3535
3536    if (ConditionPassed(opcode))
3537    {
3538        uint32_t n;
3539        uint32_t registers = 0;
3540        bool wback;
3541        const uint32_t addr_byte_size = GetAddressByteSize();
3542
3543        // EncodingSpecificOperations();
3544        switch (encoding)
3545        {
3546            case eEncodingA1:
3547                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3548                n = Bits32 (opcode, 19, 16);
3549                registers = Bits32 (opcode, 15, 0);
3550                wback = BitIsSet (opcode, 21);
3551
3552                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3553                if ((n == 15) || (BitCount (registers) < 1))
3554                    return false;
3555
3556                break;
3557
3558            default:
3559                return false;
3560        }
3561        // address = R[n] - 4*BitCount(registers) + 4;
3562
3563        int32_t offset = 0;
3564        addr_t Rn = ReadCoreReg (n, &success);
3565
3566        if (!success)
3567            return false;
3568
3569        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3570
3571        EmulateInstruction::Context context;
3572        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3573        RegisterInfo dwarf_reg;
3574        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3575        context.SetRegisterPlusOffset (dwarf_reg, offset);
3576
3577        // for i = 0 to 14
3578        for (int i = 0; i < 14; ++i)
3579        {
3580            // if registers<i> == '1' then
3581            if (BitIsSet (registers, i))
3582            {
3583                  // R[i] = MemA[address,4]; address = address + 4;
3584                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3585                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3586                  if (!success)
3587                      return false;
3588                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3589                      return false;
3590                  offset += addr_byte_size;
3591            }
3592        }
3593
3594        // if registers<15> == '1' then
3595        //     LoadWritePC(MemA[address,4]);
3596        if (BitIsSet (registers, 15))
3597        {
3598            context.SetRegisterPlusOffset (dwarf_reg, offset);
3599            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3600            if (!success)
3601                return false;
3602            // In ARMv5T and above, this is an interworking branch.
3603            if (!LoadWritePC(context, data))
3604                return false;
3605        }
3606
3607        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3608        if (wback && BitIsClear (registers, n))
3609        {
3610            if (!success)
3611                return false;
3612
3613            offset = (addr_byte_size * BitCount (registers)) * -1;
3614            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3615            context.SetImmediateSigned (offset);
3616            addr_t addr = Rn + offset;
3617            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3618                return false;
3619        }
3620
3621        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3622        if (wback && BitIsSet (registers, n))
3623            return WriteBits32Unknown (n);
3624    }
3625    return true;
3626}
3627
3628// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3629// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3630// be optionally written back to the base register.
3631bool
3632EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3633{
3634#if 0
3635    // ARM pseudo code...
3636    if ConditionPassed() then
3637        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3638        address = R[n] - 4*BitCount(registers);
3639
3640        for i = 0 to 14
3641            if registers<i> == '1' then
3642                  R[i] = MemA[address,4]; address = address + 4;
3643        if registers<15> == '1' then
3644                  LoadWritePC(MemA[address,4]);
3645
3646        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3647        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3648#endif
3649
3650    bool success = false;
3651
3652    if (ConditionPassed(opcode))
3653    {
3654        uint32_t n;
3655        uint32_t registers = 0;
3656        bool wback;
3657        const uint32_t addr_byte_size = GetAddressByteSize();
3658        switch (encoding)
3659        {
3660            case eEncodingT1:
3661                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3662                n = Bits32 (opcode, 19, 16);
3663                registers = Bits32 (opcode, 15, 0);
3664                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3665                wback = BitIsSet (opcode, 21);
3666
3667                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3668                if ((n == 15)
3669                    || (BitCount (registers) < 2)
3670                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3671                    return false;
3672
3673                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3674                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3675                    return false;
3676
3677                // if wback && registers<n> == '1' then UNPREDICTABLE;
3678                if (wback && BitIsSet (registers, n))
3679                    return false;
3680
3681                break;
3682
3683            case eEncodingA1:
3684                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3685                n = Bits32 (opcode, 19, 16);
3686                registers = Bits32 (opcode, 15, 0);
3687                wback = BitIsSet (opcode, 21);
3688
3689                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3690                if ((n == 15) || (BitCount (registers) < 1))
3691                    return false;
3692
3693                break;
3694
3695            default:
3696                return false;
3697        }
3698
3699        // address = R[n] - 4*BitCount(registers);
3700
3701        int32_t offset = 0;
3702        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3703
3704        if (!success)
3705            return false;
3706
3707        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3708        EmulateInstruction::Context context;
3709        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3710        RegisterInfo dwarf_reg;
3711        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3712        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3713
3714        for (int i = 0; i < 14; ++i)
3715        {
3716            if (BitIsSet (registers, i))
3717            {
3718                // R[i] = MemA[address,4]; address = address + 4;
3719                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3720                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3721                if (!success)
3722                    return false;
3723
3724                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3725                    return false;
3726
3727                offset += addr_byte_size;
3728            }
3729        }
3730
3731        // if registers<15> == '1' then
3732        //     LoadWritePC(MemA[address,4]);
3733        if (BitIsSet (registers, 15))
3734        {
3735            context.SetRegisterPlusOffset (dwarf_reg, offset);
3736            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3737            if (!success)
3738                return false;
3739            // In ARMv5T and above, this is an interworking branch.
3740            if (!LoadWritePC(context, data))
3741                return false;
3742        }
3743
3744        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3745        if (wback && BitIsClear (registers, n))
3746        {
3747            if (!success)
3748                return false;
3749
3750            offset = (addr_byte_size * BitCount (registers)) * -1;
3751            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3752            context.SetImmediateSigned (offset);
3753            addr_t addr = Rn + offset;
3754            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3755                return false;
3756        }
3757
3758        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3759        if (wback && BitIsSet (registers, n))
3760            return WriteBits32Unknown (n);
3761    }
3762    return true;
3763}
3764
3765// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3766// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3767// optinoally be written back to the base register.
3768bool
3769EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3770{
3771#if 0
3772    if ConditionPassed() then
3773        EncodingSpecificOperations();
3774        address = R[n] + 4;
3775
3776        for i = 0 to 14
3777            if registers<i> == '1' then
3778                  R[i] = MemA[address,4]; address = address + 4;
3779        if registers<15> == '1' then
3780            LoadWritePC(MemA[address,4]);
3781
3782        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3783        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3784#endif
3785
3786    bool success = false;
3787
3788    if (ConditionPassed(opcode))
3789    {
3790        uint32_t n;
3791        uint32_t registers = 0;
3792        bool wback;
3793        const uint32_t addr_byte_size = GetAddressByteSize();
3794        switch (encoding)
3795        {
3796            case eEncodingA1:
3797                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3798                n = Bits32 (opcode, 19, 16);
3799                registers = Bits32 (opcode, 15, 0);
3800                wback = BitIsSet (opcode, 21);
3801
3802                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3803                if ((n == 15) || (BitCount (registers) < 1))
3804                    return false;
3805
3806                break;
3807            default:
3808                return false;
3809        }
3810        // address = R[n] + 4;
3811
3812        int32_t offset = 0;
3813        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3814
3815        if (!success)
3816            return false;
3817
3818        addr_t address = Rn + addr_byte_size;
3819
3820        EmulateInstruction::Context context;
3821        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3822        RegisterInfo dwarf_reg;
3823        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3824        context.SetRegisterPlusOffset (dwarf_reg, offset);
3825
3826        for (int i = 0; i < 14; ++i)
3827        {
3828            if (BitIsSet (registers, i))
3829            {
3830                // R[i] = MemA[address,4]; address = address + 4;
3831
3832                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3833                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3834                if (!success)
3835                    return false;
3836
3837                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3838                    return false;
3839
3840                offset += addr_byte_size;
3841            }
3842        }
3843
3844        // if registers<15> == '1' then
3845        //     LoadWritePC(MemA[address,4]);
3846        if (BitIsSet (registers, 15))
3847        {
3848            context.SetRegisterPlusOffset (dwarf_reg, offset);
3849            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3850            if (!success)
3851                return false;
3852            // In ARMv5T and above, this is an interworking branch.
3853            if (!LoadWritePC(context, data))
3854                return false;
3855        }
3856
3857        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3858        if (wback && BitIsClear (registers, n))
3859        {
3860            if (!success)
3861                return false;
3862
3863            offset = addr_byte_size * BitCount (registers);
3864            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3865            context.SetImmediateSigned (offset);
3866            addr_t addr = Rn + offset;
3867            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3868                return false;
3869        }
3870
3871        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3872        if (wback && BitIsSet (registers, n))
3873            return WriteBits32Unknown (n);
3874    }
3875    return true;
3876}
3877
3878// Load Register (immediate) calculates an address from a base register value and
3879// an immediate offset, loads a word from memory, and writes to a register.
3880// LDR (immediate, Thumb)
3881bool
3882EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3883{
3884#if 0
3885    // ARM pseudo code...
3886    if (ConditionPassed())
3887    {
3888        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3889        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3890        address = if index then offset_addr else R[n];
3891        data = MemU[address,4];
3892        if wback then R[n] = offset_addr;
3893        if t == 15 then
3894            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3895        elsif UnalignedSupport() || address<1:0> = '00' then
3896            R[t] = data;
3897        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3898    }
3899#endif
3900
3901    bool success = false;
3902
3903    if (ConditionPassed(opcode))
3904    {
3905        uint32_t Rt; // the destination register
3906        uint32_t Rn; // the base register
3907        uint32_t imm32; // the immediate offset used to form the address
3908        addr_t offset_addr; // the offset address
3909        addr_t address; // the calculated address
3910        uint32_t data; // the literal data value from memory load
3911        bool add, index, wback;
3912        switch (encoding) {
3913            case eEncodingT1:
3914                Rt = Bits32(opcode, 2, 0);
3915                Rn = Bits32(opcode, 5, 3);
3916                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3917                // index = TRUE; add = TRUE; wback = FALSE
3918                add = true;
3919                index = true;
3920                wback = false;
3921
3922                break;
3923
3924            case eEncodingT2:
3925                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3926                Rt = Bits32 (opcode, 10, 8);
3927                Rn = 13;
3928                imm32 = Bits32 (opcode, 7, 0) << 2;
3929
3930                // index = TRUE; add = TRUE; wback = FALSE;
3931                index = true;
3932                add = true;
3933                wback = false;
3934
3935                break;
3936
3937            case eEncodingT3:
3938                // if Rn == '1111' then SEE LDR (literal);
3939                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3940                Rt = Bits32 (opcode, 15, 12);
3941                Rn = Bits32 (opcode, 19, 16);
3942                imm32 = Bits32 (opcode, 11, 0);
3943
3944                // index = TRUE; add = TRUE; wback = FALSE;
3945                index = true;
3946                add = true;
3947                wback = false;
3948
3949                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3950                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3951                    return false;
3952
3953                break;
3954
3955            case eEncodingT4:
3956                // if Rn == '1111' then SEE LDR (literal);
3957                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3958                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3959                // if P == '0' && W == '0' then UNDEFINED;
3960                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3961                    return false;
3962
3963                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3964                Rt = Bits32 (opcode, 15, 12);
3965                Rn = Bits32 (opcode, 19, 16);
3966                imm32 = Bits32 (opcode, 7, 0);
3967
3968                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3969                index = BitIsSet (opcode, 10);
3970                add = BitIsSet (opcode, 9);
3971                wback = BitIsSet (opcode, 8);
3972
3973                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3974                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3975                    return false;
3976
3977                break;
3978
3979            default:
3980                return false;
3981        }
3982        uint32_t base = ReadCoreReg (Rn, &success);
3983        if (!success)
3984            return false;
3985        if (add)
3986            offset_addr = base + imm32;
3987        else
3988            offset_addr = base - imm32;
3989
3990        address = (index ? offset_addr : base);
3991
3992        RegisterInfo base_reg;
3993        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3994        if (wback)
3995        {
3996            EmulateInstruction::Context ctx;
3997            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3998            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3999
4000            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4001                return false;
4002        }
4003
4004        // Prepare to write to the Rt register.
4005        EmulateInstruction::Context context;
4006        context.type = EmulateInstruction::eContextRegisterLoad;
4007        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4008
4009        // Read memory from the address.
4010        data = MemURead(context, address, 4, 0, &success);
4011        if (!success)
4012            return false;
4013
4014        if (Rt == 15)
4015        {
4016            if (Bits32(address, 1, 0) == 0)
4017            {
4018                if (!LoadWritePC(context, data))
4019                    return false;
4020            }
4021            else
4022                return false;
4023        }
4024        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4025        {
4026            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4027                return false;
4028        }
4029        else
4030            WriteBits32Unknown (Rt);
4031    }
4032    return true;
4033}
4034
4035// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4036// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4037// of those locations can optionally be written back to the base register.
4038bool
4039EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4040{
4041#if 0
4042    if ConditionPassed() then
4043        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4044        address = R[n];
4045
4046        for i = 0 to 14
4047            if registers<i> == '1' then
4048                if i == n && wback && i != LowestSetBit(registers) then
4049                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4050                else
4051                    MemA[address,4] = R[i];
4052                address = address + 4;
4053
4054        if registers<15> == '1' then // Only possible for encoding A1
4055            MemA[address,4] = PCStoreValue();
4056        if wback then R[n] = R[n] + 4*BitCount(registers);
4057#endif
4058
4059    bool success = false;
4060
4061    if (ConditionPassed(opcode))
4062    {
4063        uint32_t n;
4064        uint32_t registers = 0;
4065        bool wback;
4066        const uint32_t addr_byte_size = GetAddressByteSize();
4067
4068        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4069        switch (encoding)
4070        {
4071            case eEncodingT1:
4072                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4073                n = Bits32 (opcode, 10, 8);
4074                registers = Bits32 (opcode, 7, 0);
4075                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4076                wback = true;
4077
4078                // if BitCount(registers) < 1 then UNPREDICTABLE;
4079                if (BitCount (registers) < 1)
4080                    return false;
4081
4082                break;
4083
4084            case eEncodingT2:
4085                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4086                n = Bits32 (opcode, 19, 16);
4087                registers = Bits32 (opcode, 15, 0);
4088                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4089                wback = BitIsSet (opcode, 21);
4090
4091                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4092                if ((n == 15) || (BitCount (registers) < 2))
4093                    return false;
4094
4095                // if wback && registers<n> == '1' then UNPREDICTABLE;
4096                if (wback && BitIsSet (registers, n))
4097                    return false;
4098
4099                break;
4100
4101            case eEncodingA1:
4102                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4103                n = Bits32 (opcode, 19, 16);
4104                registers = Bits32 (opcode, 15, 0);
4105                wback = BitIsSet (opcode, 21);
4106
4107                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4108                if ((n == 15) || (BitCount (registers) < 1))
4109                    return false;
4110
4111                break;
4112
4113            default:
4114                return false;
4115        }
4116
4117        // address = R[n];
4118        int32_t offset = 0;
4119        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4120        if (!success)
4121            return false;
4122
4123        EmulateInstruction::Context context;
4124        context.type = EmulateInstruction::eContextRegisterStore;
4125        RegisterInfo base_reg;
4126        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4127
4128        // for i = 0 to 14
4129        uint32_t lowest_set_bit = 14;
4130        for (uint32_t i = 0; i < 14; ++i)
4131        {
4132            // if registers<i> == '1' then
4133            if (BitIsSet (registers, i))
4134            {
4135                  if (i < lowest_set_bit)
4136                      lowest_set_bit = i;
4137                  // if i == n && wback && i != LowestSetBit(registers) then
4138                  if ((i == n) && wback && (i != lowest_set_bit))
4139                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4140                      WriteBits32UnknownToMemory (address + offset);
4141                  else
4142                  {
4143                     // MemA[address,4] = R[i];
4144                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4145                      if (!success)
4146                          return false;
4147
4148                      RegisterInfo data_reg;
4149                      GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4150                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4151                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
4152                          return false;
4153                  }
4154
4155                  // address = address + 4;
4156                  offset += addr_byte_size;
4157            }
4158        }
4159
4160        // if registers<15> == '1' then // Only possible for encoding A1
4161        //     MemA[address,4] = PCStoreValue();
4162        if (BitIsSet (registers, 15))
4163        {
4164            RegisterInfo pc_reg;
4165            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4166            context.SetRegisterPlusOffset (pc_reg, 8);
4167            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4168            if (!success)
4169                return false;
4170
4171            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4172                return false;
4173        }
4174
4175        // if wback then R[n] = R[n] + 4*BitCount(registers);
4176        if (wback)
4177        {
4178            offset = addr_byte_size * BitCount (registers);
4179            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4180            context.SetImmediateSigned (offset);
4181            addr_t data = address + offset;
4182            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4183                return false;
4184        }
4185    }
4186    return true;
4187}
4188
4189// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4190// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4191// of those locations can optionally be written back to the base register.
4192bool
4193EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4194{
4195#if 0
4196    if ConditionPassed() then
4197        EncodingSpecificOperations();
4198        address = R[n] - 4*BitCount(registers) + 4;
4199
4200        for i = 0 to 14
4201            if registers<i> == '1' then
4202                if i == n && wback && i != LowestSetBit(registers) then
4203                    MemA[address,4] = bits(32) UNKNOWN;
4204                else
4205                    MemA[address,4] = R[i];
4206                address = address + 4;
4207
4208        if registers<15> == '1' then
4209            MemA[address,4] = PCStoreValue();
4210
4211        if wback then R[n] = R[n] - 4*BitCount(registers);
4212#endif
4213
4214    bool success = false;
4215
4216    if (ConditionPassed(opcode))
4217    {
4218        uint32_t n;
4219        uint32_t registers = 0;
4220        bool wback;
4221        const uint32_t addr_byte_size = GetAddressByteSize();
4222
4223        // EncodingSpecificOperations();
4224        switch (encoding)
4225        {
4226            case eEncodingA1:
4227                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4228                n = Bits32 (opcode, 19, 16);
4229                registers = Bits32 (opcode, 15, 0);
4230                wback = BitIsSet (opcode, 21);
4231
4232                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4233                if ((n == 15) || (BitCount (registers) < 1))
4234                    return false;
4235                break;
4236            default:
4237                return false;
4238        }
4239
4240        // address = R[n] - 4*BitCount(registers) + 4;
4241        int32_t offset = 0;
4242        addr_t Rn = ReadCoreReg (n, &success);
4243        if (!success)
4244            return false;
4245
4246        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4247
4248        EmulateInstruction::Context context;
4249        context.type = EmulateInstruction::eContextRegisterStore;
4250        RegisterInfo base_reg;
4251        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4252
4253        // for i = 0 to 14
4254        uint32_t lowest_bit_set = 14;
4255        for (uint32_t i = 0; i < 14; ++i)
4256        {
4257            // if registers<i> == '1' then
4258            if (BitIsSet (registers, i))
4259            {
4260                if (i < lowest_bit_set)
4261                    lowest_bit_set = i;
4262                //if i == n && wback && i != LowestSetBit(registers) then
4263                if ((i == n) && wback && (i != lowest_bit_set))
4264                    // MemA[address,4] = bits(32) UNKNOWN;
4265                    WriteBits32UnknownToMemory (address + offset);
4266                else
4267                {
4268                    // MemA[address,4] = R[i];
4269                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4270                    if (!success)
4271                        return false;
4272
4273                    RegisterInfo data_reg;
4274                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4275                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4276                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4277                        return false;
4278                }
4279
4280                // address = address + 4;
4281                offset += addr_byte_size;
4282            }
4283        }
4284
4285        // if registers<15> == '1' then
4286        //    MemA[address,4] = PCStoreValue();
4287        if (BitIsSet (registers, 15))
4288        {
4289            RegisterInfo pc_reg;
4290            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4291            context.SetRegisterPlusOffset (pc_reg, 8);
4292            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4293            if (!success)
4294                return false;
4295
4296            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4297                return false;
4298        }
4299
4300        // if wback then R[n] = R[n] - 4*BitCount(registers);
4301        if (wback)
4302        {
4303            offset = (addr_byte_size * BitCount (registers)) * -1;
4304            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4305            context.SetImmediateSigned (offset);
4306            addr_t data = Rn + offset;
4307            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4308                return false;
4309        }
4310    }
4311    return true;
4312}
4313
4314// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4315// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4316// those locations can optionally be written back to the base register.
4317bool
4318EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4319{
4320#if 0
4321    if ConditionPassed() then
4322        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4323        address = R[n] - 4*BitCount(registers);
4324
4325        for i = 0 to 14
4326            if registers<i> == '1' then
4327                if i == n && wback && i != LowestSetBit(registers) then
4328                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4329                else
4330                    MemA[address,4] = R[i];
4331                address = address + 4;
4332
4333        if registers<15> == '1' then // Only possible for encoding A1
4334            MemA[address,4] = PCStoreValue();
4335
4336        if wback then R[n] = R[n] - 4*BitCount(registers);
4337#endif
4338
4339
4340    bool success = false;
4341
4342    if (ConditionPassed(opcode))
4343    {
4344        uint32_t n;
4345        uint32_t registers = 0;
4346        bool wback;
4347        const uint32_t addr_byte_size = GetAddressByteSize();
4348
4349        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4350        switch (encoding)
4351        {
4352            case eEncodingT1:
4353                // if W == '1' && Rn == '1101' then SEE PUSH;
4354                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4355                {
4356                    // See PUSH
4357                }
4358                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4359                n = Bits32 (opcode, 19, 16);
4360                registers = Bits32 (opcode, 15, 0);
4361                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4362                wback = BitIsSet (opcode, 21);
4363                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4364                if ((n == 15) || BitCount (registers) < 2)
4365                    return false;
4366                // if wback && registers<n> == '1' then UNPREDICTABLE;
4367                if (wback && BitIsSet (registers, n))
4368                    return false;
4369                break;
4370
4371            case eEncodingA1:
4372                // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4373                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4374                {
4375                    // See Push
4376                }
4377                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4378                n = Bits32 (opcode, 19, 16);
4379                registers = Bits32 (opcode, 15, 0);
4380                wback = BitIsSet (opcode, 21);
4381                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4382                if ((n == 15) || BitCount (registers) < 1)
4383                    return false;
4384                break;
4385
4386            default:
4387                return false;
4388        }
4389
4390        // address = R[n] - 4*BitCount(registers);
4391
4392        int32_t offset = 0;
4393        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4394        if (!success)
4395        return false;
4396
4397        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4398
4399        EmulateInstruction::Context context;
4400        context.type = EmulateInstruction::eContextRegisterStore;
4401        RegisterInfo base_reg;
4402        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4403
4404        // for i = 0 to 14
4405        uint32_t lowest_set_bit = 14;
4406        for (uint32_t i = 0; i < 14; ++i)
4407        {
4408            // if registers<i> == '1' then
4409            if (BitIsSet (registers, i))
4410            {
4411                if (i < lowest_set_bit)
4412                    lowest_set_bit = i;
4413                // if i == n && wback && i != LowestSetBit(registers) then
4414                if ((i == n) && wback && (i != lowest_set_bit))
4415                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4416                    WriteBits32UnknownToMemory (address + offset);
4417                else
4418                {
4419                    // MemA[address,4] = R[i];
4420                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4421                    if (!success)
4422                        return false;
4423
4424                    RegisterInfo data_reg;
4425                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4426                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4427                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4428                        return false;
4429                }
4430
4431                // address = address + 4;
4432                offset += addr_byte_size;
4433            }
4434        }
4435
4436        // if registers<15> == '1' then // Only possible for encoding A1
4437        //     MemA[address,4] = PCStoreValue();
4438        if (BitIsSet (registers, 15))
4439        {
4440            RegisterInfo pc_reg;
4441            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4442            context.SetRegisterPlusOffset (pc_reg, 8);
4443            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4444            if (!success)
4445                return false;
4446
4447            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4448                return false;
4449        }
4450
4451        // if wback then R[n] = R[n] - 4*BitCount(registers);
4452        if (wback)
4453        {
4454            offset = (addr_byte_size * BitCount (registers)) * -1;
4455            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4456            context.SetImmediateSigned (offset);
4457            addr_t data = Rn + offset;
4458            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4459                return false;
4460        }
4461    }
4462    return true;
4463}
4464
4465// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4466// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4467// of those locations can optionally be written back to the base register.
4468bool
4469EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4470{
4471#if 0
4472    if ConditionPassed() then
4473        EncodingSpecificOperations();
4474        address = R[n] + 4;
4475
4476        for i = 0 to 14
4477            if registers<i> == '1' then
4478                if i == n && wback && i != LowestSetBit(registers) then
4479                    MemA[address,4] = bits(32) UNKNOWN;
4480                else
4481                    MemA[address,4] = R[i];
4482                address = address + 4;
4483
4484        if registers<15> == '1' then
4485            MemA[address,4] = PCStoreValue();
4486
4487        if wback then R[n] = R[n] + 4*BitCount(registers);
4488#endif
4489
4490    bool success = false;
4491
4492    if (ConditionPassed(opcode))
4493    {
4494        uint32_t n;
4495        uint32_t registers = 0;
4496        bool wback;
4497        const uint32_t addr_byte_size = GetAddressByteSize();
4498
4499        // EncodingSpecificOperations();
4500        switch (encoding)
4501        {
4502            case eEncodingA1:
4503                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4504                n = Bits32 (opcode, 19, 16);
4505                registers = Bits32 (opcode, 15, 0);
4506                wback = BitIsSet (opcode, 21);
4507
4508                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4509                if ((n == 15) && (BitCount (registers) < 1))
4510                    return false;
4511                break;
4512            default:
4513                return false;
4514        }
4515        // address = R[n] + 4;
4516
4517        int32_t offset = 0;
4518        addr_t Rn = ReadCoreReg (n, &success);
4519        if (!success)
4520            return false;
4521
4522        addr_t address = Rn + addr_byte_size;
4523
4524        EmulateInstruction::Context context;
4525        context.type = EmulateInstruction::eContextRegisterStore;
4526        RegisterInfo base_reg;
4527        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4528
4529        uint32_t lowest_set_bit = 14;
4530        // for i = 0 to 14
4531        for (uint32_t i = 0; i < 14; ++i)
4532        {
4533            // if registers<i> == '1' then
4534            if (BitIsSet (registers, i))
4535            {
4536                if (i < lowest_set_bit)
4537                    lowest_set_bit = i;
4538                // if i == n && wback && i != LowestSetBit(registers) then
4539                if ((i == n) && wback && (i != lowest_set_bit))
4540                    // MemA[address,4] = bits(32) UNKNOWN;
4541                    WriteBits32UnknownToMemory (address + offset);
4542                // else
4543                else
4544                {
4545                    // MemA[address,4] = R[i];
4546                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4547                    if (!success)
4548                        return false;
4549
4550                    RegisterInfo data_reg;
4551                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4552                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4553                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4554                        return false;
4555                }
4556
4557                // address = address + 4;
4558                offset += addr_byte_size;
4559            }
4560        }
4561
4562        // if registers<15> == '1' then
4563            // MemA[address,4] = PCStoreValue();
4564        if (BitIsSet (registers, 15))
4565        {
4566            RegisterInfo pc_reg;
4567            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4568            context.SetRegisterPlusOffset (pc_reg, 8);
4569            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4570            if (!success)
4571            return false;
4572
4573            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4574                return false;
4575        }
4576
4577        // if wback then R[n] = R[n] + 4*BitCount(registers);
4578        if (wback)
4579        {
4580            offset = addr_byte_size * BitCount (registers);
4581            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4582            context.SetImmediateSigned (offset);
4583            addr_t data = Rn + offset;
4584            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4585                return false;
4586        }
4587    }
4588    return true;
4589}
4590
4591// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4592// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4593bool
4594EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4595{
4596#if 0
4597    if ConditionPassed() then
4598        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4599        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4600        address = if index then offset_addr else R[n];
4601        if UnalignedSupport() || address<1:0> == '00' then
4602            MemU[address,4] = R[t];
4603        else // Can only occur before ARMv7
4604            MemU[address,4] = bits(32) UNKNOWN;
4605        if wback then R[n] = offset_addr;
4606#endif
4607
4608    bool success = false;
4609
4610    if (ConditionPassed(opcode))
4611    {
4612        const uint32_t addr_byte_size = GetAddressByteSize();
4613
4614        uint32_t t;
4615        uint32_t n;
4616        uint32_t imm32;
4617        bool index;
4618        bool add;
4619        bool wback;
4620        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4621        switch (encoding)
4622        {
4623            case eEncodingT1:
4624                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4625                t = Bits32 (opcode, 2, 0);
4626                n = Bits32 (opcode, 5, 3);
4627                imm32 = Bits32 (opcode, 10, 6) << 2;
4628
4629                // index = TRUE; add = TRUE; wback = FALSE;
4630                index = true;
4631                add = false;
4632                wback = false;
4633                break;
4634
4635            case eEncodingT2:
4636                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4637                t = Bits32 (opcode, 10, 8);
4638                n = 13;
4639                imm32 = Bits32 (opcode, 7, 0) << 2;
4640
4641                // index = TRUE; add = TRUE; wback = FALSE;
4642                index = true;
4643                add = true;
4644                wback = false;
4645                break;
4646
4647            case eEncodingT3:
4648                // if Rn == '1111' then UNDEFINED;
4649                if (Bits32 (opcode, 19, 16) == 15)
4650                    return false;
4651
4652                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4653                t = Bits32 (opcode, 15, 12);
4654                n = Bits32 (opcode, 19, 16);
4655                imm32 = Bits32 (opcode, 11, 0);
4656
4657                // index = TRUE; add = TRUE; wback = FALSE;
4658                index = true;
4659                add = true;
4660                wback = false;
4661
4662                // if t == 15 then UNPREDICTABLE;
4663                if (t == 15)
4664                    return false;
4665                break;
4666
4667            case eEncodingT4:
4668                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4669                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4670                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4671                if ((Bits32 (opcode, 19, 16) == 15)
4672                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4673                    return false;
4674
4675                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4676                t = Bits32 (opcode, 15, 12);
4677                n = Bits32 (opcode, 19, 16);
4678                imm32 = Bits32 (opcode, 7, 0);
4679
4680                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4681                index = BitIsSet (opcode, 10);
4682                add = BitIsSet (opcode, 9);
4683                wback = BitIsSet (opcode, 8);
4684
4685                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4686                if ((t == 15) || (wback && (n == t)))
4687                    return false;
4688                break;
4689
4690            default:
4691                return false;
4692        }
4693
4694        addr_t offset_addr;
4695        addr_t address;
4696
4697        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4698        uint32_t base_address = ReadCoreReg (n, &success);
4699        if (!success)
4700            return false;
4701
4702        if (add)
4703            offset_addr = base_address + imm32;
4704        else
4705            offset_addr = base_address - imm32;
4706
4707        // address = if index then offset_addr else R[n];
4708        if (index)
4709            address = offset_addr;
4710        else
4711            address = base_address;
4712
4713        EmulateInstruction::Context context;
4714        context.type = eContextRegisterStore;
4715        RegisterInfo base_reg;
4716        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4717
4718        // if UnalignedSupport() || address<1:0> == '00' then
4719        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4720        {
4721            // MemU[address,4] = R[t];
4722            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4723            if (!success)
4724                return false;
4725
4726            RegisterInfo data_reg;
4727            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4728            int32_t offset = address - base_address;
4729            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4730            if (!MemUWrite (context, address, data, addr_byte_size))
4731                return false;
4732        }
4733        else
4734        {
4735            // MemU[address,4] = bits(32) UNKNOWN;
4736            WriteBits32UnknownToMemory (address);
4737        }
4738
4739        // if wback then R[n] = offset_addr;
4740        if (wback)
4741        {
4742            context.type = eContextRegisterLoad;
4743            context.SetAddress (offset_addr);
4744            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4745                return false;
4746        }
4747    }
4748    return true;
4749}
4750
4751// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4752// word from a register to memory.   The offset register value can optionally be shifted.
4753bool
4754EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4755{
4756#if 0
4757    if ConditionPassed() then
4758        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4759        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4760        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4761        address = if index then offset_addr else R[n];
4762        if t == 15 then // Only possible for encoding A1
4763            data = PCStoreValue();
4764        else
4765            data = R[t];
4766        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4767            MemU[address,4] = data;
4768        else // Can only occur before ARMv7
4769            MemU[address,4] = bits(32) UNKNOWN;
4770        if wback then R[n] = offset_addr;
4771#endif
4772
4773    bool success = false;
4774
4775    if (ConditionPassed(opcode))
4776    {
4777        const uint32_t addr_byte_size = GetAddressByteSize();
4778
4779        uint32_t t;
4780        uint32_t n;
4781        uint32_t m;
4782        ARM_ShifterType shift_t;
4783        uint32_t shift_n;
4784        bool index;
4785        bool add;
4786        bool wback;
4787
4788        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4789        switch (encoding)
4790        {
4791            case eEncodingT1:
4792                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4793                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4794                t = Bits32 (opcode, 2, 0);
4795                n = Bits32 (opcode, 5, 3);
4796                m = Bits32 (opcode, 8, 6);
4797
4798                // index = TRUE; add = TRUE; wback = FALSE;
4799                index = true;
4800                add = true;
4801                wback = false;
4802
4803                // (shift_t, shift_n) = (SRType_LSL, 0);
4804                shift_t = SRType_LSL;
4805                shift_n = 0;
4806                break;
4807
4808            case eEncodingT2:
4809                // if Rn == '1111' then UNDEFINED;
4810                if (Bits32 (opcode, 19, 16) == 15)
4811                    return false;
4812
4813                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4814                t = Bits32 (opcode, 15, 12);
4815                n = Bits32 (opcode, 19, 16);
4816                m = Bits32 (opcode, 3, 0);
4817
4818                // index = TRUE; add = TRUE; wback = FALSE;
4819                index = true;
4820                add = true;
4821                wback = false;
4822
4823                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4824                shift_t = SRType_LSL;
4825                shift_n = Bits32 (opcode, 5, 4);
4826
4827                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4828                if ((t == 15) || (BadReg (m)))
4829                    return false;
4830                break;
4831
4832            case eEncodingA1:
4833            {
4834                // if P == '0' && W == '1' then SEE STRT;
4835                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4836                t = Bits32 (opcode, 15, 12);
4837                n = Bits32 (opcode, 19, 16);
4838                m = Bits32 (opcode, 3, 0);
4839
4840                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4841                index = BitIsSet (opcode, 24);
4842                add = BitIsSet (opcode, 23);
4843                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4844
4845                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4846                uint32_t typ = Bits32 (opcode, 6, 5);
4847                uint32_t imm5 = Bits32 (opcode, 11, 7);
4848                shift_n = DecodeImmShift(typ, imm5, shift_t);
4849
4850                // if m == 15 then UNPREDICTABLE;
4851                if (m == 15)
4852                    return false;
4853
4854                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4855                if (wback && ((n == 15) || (n == t)))
4856                    return false;
4857
4858                break;
4859            }
4860            default:
4861                return false;
4862        }
4863
4864        addr_t offset_addr;
4865        addr_t address;
4866        int32_t offset = 0;
4867
4868        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4869        if (!success)
4870            return false;
4871
4872        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4873        if (!success)
4874            return false;
4875
4876        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4877        offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4878        if (!success)
4879            return false;
4880
4881        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4882        if (add)
4883            offset_addr = base_address + offset;
4884        else
4885            offset_addr = base_address - offset;
4886
4887        // address = if index then offset_addr else R[n];
4888        if (index)
4889            address = offset_addr;
4890        else
4891            address = base_address;
4892
4893        uint32_t data;
4894        // if t == 15 then // Only possible for encoding A1
4895        if (t == 15)
4896            // data = PCStoreValue();
4897            data = ReadCoreReg (PC_REG, &success);
4898        else
4899            // data = R[t];
4900            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4901
4902        if (!success)
4903            return false;
4904
4905        EmulateInstruction::Context context;
4906        context.type = eContextRegisterStore;
4907
4908        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4909        if (UnalignedSupport ()
4910            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4911            || CurrentInstrSet() == eModeARM)
4912        {
4913            // MemU[address,4] = data;
4914
4915            RegisterInfo base_reg;
4916            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4917
4918            RegisterInfo data_reg;
4919            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4920
4921            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4922            if (!MemUWrite (context, address, data, addr_byte_size))
4923                return false;
4924
4925        }
4926        else
4927            // MemU[address,4] = bits(32) UNKNOWN;
4928            WriteBits32UnknownToMemory (address);
4929
4930        // if wback then R[n] = offset_addr;
4931        if (wback)
4932        {
4933            context.type = eContextRegisterLoad;
4934            context.SetAddress (offset_addr);
4935            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4936                return false;
4937        }
4938
4939    }
4940    return true;
4941}
4942
4943bool
4944EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4945{
4946#if 0
4947    if ConditionPassed() then
4948        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4949        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4950        address = if index then offset_addr else R[n];
4951        MemU[address,1] = R[t]<7:0>;
4952        if wback then R[n] = offset_addr;
4953#endif
4954
4955
4956    bool success = false;
4957
4958    if (ConditionPassed(opcode))
4959    {
4960        uint32_t t;
4961        uint32_t n;
4962        uint32_t imm32;
4963        bool index;
4964        bool add;
4965        bool wback;
4966        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4967        switch (encoding)
4968        {
4969            case eEncodingT1:
4970                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4971                t = Bits32 (opcode, 2, 0);
4972                n = Bits32 (opcode, 5, 3);
4973                imm32 = Bits32 (opcode, 10, 6);
4974
4975                // index = TRUE; add = TRUE; wback = FALSE;
4976                index = true;
4977                add = true;
4978                wback = false;
4979                break;
4980
4981            case eEncodingT2:
4982                // if Rn == '1111' then UNDEFINED;
4983                if (Bits32 (opcode, 19, 16) == 15)
4984                    return false;
4985
4986                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4987                t = Bits32 (opcode, 15, 12);
4988                n = Bits32 (opcode, 19, 16);
4989                imm32 = Bits32 (opcode, 11, 0);
4990
4991                // index = TRUE; add = TRUE; wback = FALSE;
4992                index = true;
4993                add = true;
4994                wback = false;
4995
4996                // if BadReg(t) then UNPREDICTABLE;
4997                if (BadReg (t))
4998                    return false;
4999                break;
5000
5001            case eEncodingT3:
5002                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5003                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5004                if (Bits32 (opcode, 19, 16) == 15)
5005                    return false;
5006
5007                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5008                t = Bits32 (opcode, 15, 12);
5009                n = Bits32 (opcode, 19, 16);
5010                imm32 = Bits32 (opcode, 7, 0);
5011
5012                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5013                index = BitIsSet (opcode, 10);
5014                add = BitIsSet (opcode, 9);
5015                wback = BitIsSet (opcode, 8);
5016
5017                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5018                if ((BadReg (t)) || (wback && (n == t)))
5019                    return false;
5020                break;
5021
5022            default:
5023                return false;
5024        }
5025
5026        addr_t offset_addr;
5027        addr_t address;
5028        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5029        if (!success)
5030            return false;
5031
5032        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5033        if (add)
5034            offset_addr = base_address + imm32;
5035        else
5036            offset_addr = base_address - imm32;
5037
5038        // address = if index then offset_addr else R[n];
5039        if (index)
5040            address = offset_addr;
5041        else
5042            address = base_address;
5043
5044        // MemU[address,1] = R[t]<7:0>
5045        RegisterInfo base_reg;
5046        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5047
5048        RegisterInfo data_reg;
5049        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5050
5051        EmulateInstruction::Context context;
5052        context.type = eContextRegisterStore;
5053        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5054
5055        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5056        if (!success)
5057            return false;
5058
5059        data = Bits32 (data, 7, 0);
5060
5061        if (!MemUWrite (context, address, data, 1))
5062            return false;
5063
5064        // if wback then R[n] = offset_addr;
5065        if (wback)
5066        {
5067            context.type = eContextRegisterLoad;
5068            context.SetAddress (offset_addr);
5069            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5070                return false;
5071        }
5072
5073    }
5074
5075    return true;
5076}
5077
5078// STRH (register) calculates an address from a base register value and an offset register value, and stores a
5079// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5080bool
5081EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5082{
5083#if 0
5084    if ConditionPassed() then
5085        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5086        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5087        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5088        address = if index then offset_addr else R[n];
5089        if UnalignedSupport() || address<0> == '0' then
5090            MemU[address,2] = R[t]<15:0>;
5091        else // Can only occur before ARMv7
5092            MemU[address,2] = bits(16) UNKNOWN;
5093        if wback then R[n] = offset_addr;
5094#endif
5095
5096    bool success = false;
5097
5098    if (ConditionPassed(opcode))
5099    {
5100        uint32_t t;
5101        uint32_t n;
5102        uint32_t m;
5103        bool index;
5104        bool add;
5105        bool wback;
5106        ARM_ShifterType shift_t;
5107        uint32_t shift_n;
5108
5109        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5110        switch (encoding)
5111        {
5112            case eEncodingT1:
5113                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5114                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5115                t = Bits32 (opcode, 2, 0);
5116                n = Bits32 (opcode, 5, 3);
5117                m = Bits32 (opcode, 8, 6);
5118
5119                // index = TRUE; add = TRUE; wback = FALSE;
5120                index = true;
5121                add = true;
5122                wback = false;
5123
5124                // (shift_t, shift_n) = (SRType_LSL, 0);
5125                shift_t = SRType_LSL;
5126                shift_n = 0;
5127
5128                break;
5129
5130            case eEncodingT2:
5131                // if Rn == '1111' then UNDEFINED;
5132                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5133                t = Bits32 (opcode, 15, 12);
5134                n = Bits32 (opcode, 19, 16);
5135                m = Bits32 (opcode, 3, 0);
5136                if (n == 15)
5137                    return false;
5138
5139                // index = TRUE; add = TRUE; wback = FALSE;
5140                index = true;
5141                add = true;
5142                wback = false;
5143
5144                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5145                shift_t = SRType_LSL;
5146                shift_n = Bits32 (opcode, 5, 4);
5147
5148                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5149                if (BadReg (t) || BadReg (m))
5150                    return false;
5151
5152                break;
5153
5154            case eEncodingA1:
5155                // if P == '0' && W == '1' then SEE STRHT;
5156                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5157                t = Bits32 (opcode, 15, 12);
5158                n = Bits32 (opcode, 19, 16);
5159                m = Bits32 (opcode, 3, 0);
5160
5161                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5162                index = BitIsSet (opcode, 24);
5163                add = BitIsSet (opcode, 23);
5164                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5165
5166                // (shift_t, shift_n) = (SRType_LSL, 0);
5167                shift_t = SRType_LSL;
5168                shift_n = 0;
5169
5170                // if t == 15 || m == 15 then UNPREDICTABLE;
5171                if ((t == 15) || (m == 15))
5172                    return false;
5173
5174                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5175                if (wback && ((n == 15) || (n == t)))
5176                    return false;
5177
5178                break;
5179
5180            default:
5181                return false;
5182        }
5183
5184        uint32_t Rm = ReadCoreReg (m, &success);
5185        if (!success)
5186            return false;
5187
5188        uint32_t Rn = ReadCoreReg (n, &success);
5189        if (!success)
5190            return false;
5191
5192        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5193        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5194        if (!success)
5195            return false;
5196
5197        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5198        addr_t offset_addr;
5199        if (add)
5200            offset_addr = Rn + offset;
5201        else
5202            offset_addr = Rn - offset;
5203
5204        // address = if index then offset_addr else R[n];
5205        addr_t address;
5206        if (index)
5207            address = offset_addr;
5208        else
5209            address = Rn;
5210
5211        EmulateInstruction::Context context;
5212        context.type = eContextRegisterStore;
5213        RegisterInfo base_reg;
5214        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5215        RegisterInfo offset_reg;
5216        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5217
5218        // if UnalignedSupport() || address<0> == '0' then
5219        if (UnalignedSupport() || BitIsClear (address, 0))
5220        {
5221            // MemU[address,2] = R[t]<15:0>;
5222            uint32_t Rt = ReadCoreReg (t, &success);
5223            if (!success)
5224                return false;
5225
5226            EmulateInstruction::Context context;
5227            context.type = eContextRegisterStore;
5228            RegisterInfo base_reg;
5229            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5230            RegisterInfo offset_reg;
5231            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5232            RegisterInfo data_reg;
5233            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5234            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5235
5236            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5237                return false;
5238        }
5239        else // Can only occur before ARMv7
5240        {
5241            // MemU[address,2] = bits(16) UNKNOWN;
5242        }
5243
5244        // if wback then R[n] = offset_addr;
5245        if (wback)
5246        {
5247            context.type = eContextAdjustBaseRegister;
5248            context.SetAddress (offset_addr);
5249            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5250                return false;
5251        }
5252    }
5253
5254    return true;
5255}
5256
5257// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5258// and writes the result to the destination register.  It can optionally update the condition flags
5259// based on the result.
5260bool
5261EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5262{
5263#if 0
5264    // ARM pseudo code...
5265    if ConditionPassed() then
5266        EncodingSpecificOperations();
5267        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5268        if d == 15 then         // Can only occur for ARM encoding
5269            ALUWritePC(result); // setflags is always FALSE here
5270        else
5271            R[d] = result;
5272            if setflags then
5273                APSR.N = result<31>;
5274                APSR.Z = IsZeroBit(result);
5275                APSR.C = carry;
5276                APSR.V = overflow;
5277#endif
5278
5279    bool success = false;
5280
5281    if (ConditionPassed(opcode))
5282    {
5283        uint32_t Rd, Rn;
5284        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5285        bool setflags;
5286        switch (encoding)
5287        {
5288        case eEncodingT1:
5289            Rd = Bits32(opcode, 11, 8);
5290            Rn = Bits32(opcode, 19, 16);
5291            setflags = BitIsSet(opcode, 20);
5292            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5293            if (BadReg(Rd) || BadReg(Rn))
5294                return false;
5295            break;
5296        case eEncodingA1:
5297            Rd = Bits32(opcode, 15, 12);
5298            Rn = Bits32(opcode, 19, 16);
5299            setflags = BitIsSet(opcode, 20);
5300            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5301
5302            if (Rd == 15 && setflags)
5303                return EmulateSUBSPcLrEtc (opcode, encoding);
5304            break;
5305        default:
5306            return false;
5307        }
5308
5309        // Read the first operand.
5310        int32_t val1 = ReadCoreReg(Rn, &success);
5311        if (!success)
5312            return false;
5313
5314        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5315
5316        EmulateInstruction::Context context;
5317        context.type = EmulateInstruction::eContextImmediate;
5318        context.SetNoArgs ();
5319
5320        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5321            return false;
5322    }
5323    return true;
5324}
5325
5326// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5327// register value, and writes the result to the destination register.  It can optionally update the
5328// condition flags based on the result.
5329bool
5330EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5331{
5332#if 0
5333    // ARM pseudo code...
5334    if ConditionPassed() then
5335        EncodingSpecificOperations();
5336        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5337        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5338        if d == 15 then         // Can only occur for ARM encoding
5339            ALUWritePC(result); // setflags is always FALSE here
5340        else
5341            R[d] = result;
5342            if setflags then
5343                APSR.N = result<31>;
5344                APSR.Z = IsZeroBit(result);
5345                APSR.C = carry;
5346                APSR.V = overflow;
5347#endif
5348
5349    bool success = false;
5350
5351    if (ConditionPassed(opcode))
5352    {
5353        uint32_t Rd, Rn, Rm;
5354        ARM_ShifterType shift_t;
5355        uint32_t shift_n; // the shift applied to the value read from Rm
5356        bool setflags;
5357        switch (encoding)
5358        {
5359        case eEncodingT1:
5360            Rd = Rn = Bits32(opcode, 2, 0);
5361            Rm = Bits32(opcode, 5, 3);
5362            setflags = !InITBlock();
5363            shift_t = SRType_LSL;
5364            shift_n = 0;
5365            break;
5366        case eEncodingT2:
5367            Rd = Bits32(opcode, 11, 8);
5368            Rn = Bits32(opcode, 19, 16);
5369            Rm = Bits32(opcode, 3, 0);
5370            setflags = BitIsSet(opcode, 20);
5371            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5372            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5373                return false;
5374            break;
5375        case eEncodingA1:
5376            Rd = Bits32(opcode, 15, 12);
5377            Rn = Bits32(opcode, 19, 16);
5378            Rm = Bits32(opcode, 3, 0);
5379            setflags = BitIsSet(opcode, 20);
5380            shift_n = DecodeImmShiftARM(opcode, shift_t);
5381
5382            if (Rd == 15 && setflags)
5383                return EmulateSUBSPcLrEtc (opcode, encoding);
5384            break;
5385        default:
5386            return false;
5387        }
5388
5389        // Read the first operand.
5390        int32_t val1 = ReadCoreReg(Rn, &success);
5391        if (!success)
5392            return false;
5393
5394        // Read the second operand.
5395        int32_t val2 = ReadCoreReg(Rm, &success);
5396        if (!success)
5397            return false;
5398
5399        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5400        if (!success)
5401            return false;
5402        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5403
5404        EmulateInstruction::Context context;
5405        context.type = EmulateInstruction::eContextImmediate;
5406        context.SetNoArgs ();
5407
5408        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5409            return false;
5410    }
5411    return true;
5412}
5413
5414// This instruction adds an immediate value to the PC value to form a PC-relative address,
5415// and writes the result to the destination register.
5416bool
5417EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5418{
5419#if 0
5420    // ARM pseudo code...
5421    if ConditionPassed() then
5422        EncodingSpecificOperations();
5423        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5424        if d == 15 then         // Can only occur for ARM encodings
5425            ALUWritePC(result);
5426        else
5427            R[d] = result;
5428#endif
5429
5430    bool success = false;
5431
5432    if (ConditionPassed(opcode))
5433    {
5434        uint32_t Rd;
5435        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5436        bool add;
5437        switch (encoding)
5438        {
5439        case eEncodingT1:
5440            Rd = Bits32(opcode, 10, 8);
5441            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5442            add = true;
5443            break;
5444        case eEncodingT2:
5445        case eEncodingT3:
5446            Rd = Bits32(opcode, 11, 8);
5447            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5448            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5449            if (BadReg(Rd))
5450                return false;
5451            break;
5452        case eEncodingA1:
5453        case eEncodingA2:
5454            Rd = Bits32(opcode, 15, 12);
5455            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5456            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5457            break;
5458        default:
5459            return false;
5460        }
5461
5462        // Read the PC value.
5463        uint32_t pc = ReadCoreReg(PC_REG, &success);
5464        if (!success)
5465            return false;
5466
5467        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5468
5469        EmulateInstruction::Context context;
5470        context.type = EmulateInstruction::eContextImmediate;
5471        context.SetNoArgs ();
5472
5473        if (!WriteCoreReg(context, result, Rd))
5474            return false;
5475    }
5476    return true;
5477}
5478
5479// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5480// to the destination register.  It can optionally update the condition flags based on the result.
5481bool
5482EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5483{
5484#if 0
5485    // ARM pseudo code...
5486    if ConditionPassed() then
5487        EncodingSpecificOperations();
5488        result = R[n] AND imm32;
5489        if d == 15 then         // Can only occur for ARM encoding
5490            ALUWritePC(result); // setflags is always FALSE here
5491        else
5492            R[d] = result;
5493            if setflags then
5494                APSR.N = result<31>;
5495                APSR.Z = IsZeroBit(result);
5496                APSR.C = carry;
5497                // APSR.V unchanged
5498#endif
5499
5500    bool success = false;
5501
5502    if (ConditionPassed(opcode))
5503    {
5504        uint32_t Rd, Rn;
5505        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5506        bool setflags;
5507        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5508        switch (encoding)
5509        {
5510        case eEncodingT1:
5511            Rd = Bits32(opcode, 11, 8);
5512            Rn = Bits32(opcode, 19, 16);
5513            setflags = BitIsSet(opcode, 20);
5514            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5515            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5516            if (Rd == 15 && setflags)
5517                return EmulateTSTImm(opcode, eEncodingT1);
5518            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5519                return false;
5520            break;
5521        case eEncodingA1:
5522            Rd = Bits32(opcode, 15, 12);
5523            Rn = Bits32(opcode, 19, 16);
5524            setflags = BitIsSet(opcode, 20);
5525            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5526
5527            if (Rd == 15 && setflags)
5528                return EmulateSUBSPcLrEtc (opcode, encoding);
5529            break;
5530        default:
5531            return false;
5532        }
5533
5534        // Read the first operand.
5535        uint32_t val1 = ReadCoreReg(Rn, &success);
5536        if (!success)
5537            return false;
5538
5539        uint32_t result = val1 & imm32;
5540
5541        EmulateInstruction::Context context;
5542        context.type = EmulateInstruction::eContextImmediate;
5543        context.SetNoArgs ();
5544
5545        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5546            return false;
5547    }
5548    return true;
5549}
5550
5551// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5552// and writes the result to the destination register.  It can optionally update the condition flags
5553// based on the result.
5554bool
5555EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5556{
5557#if 0
5558    // ARM pseudo code...
5559    if ConditionPassed() then
5560        EncodingSpecificOperations();
5561        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5562        result = R[n] AND shifted;
5563        if d == 15 then         // Can only occur for ARM encoding
5564            ALUWritePC(result); // setflags is always FALSE here
5565        else
5566            R[d] = result;
5567            if setflags then
5568                APSR.N = result<31>;
5569                APSR.Z = IsZeroBit(result);
5570                APSR.C = carry;
5571                // APSR.V unchanged
5572#endif
5573
5574    bool success = false;
5575
5576    if (ConditionPassed(opcode))
5577    {
5578        uint32_t Rd, Rn, Rm;
5579        ARM_ShifterType shift_t;
5580        uint32_t shift_n; // the shift applied to the value read from Rm
5581        bool setflags;
5582        uint32_t carry;
5583        switch (encoding)
5584        {
5585        case eEncodingT1:
5586            Rd = Rn = Bits32(opcode, 2, 0);
5587            Rm = Bits32(opcode, 5, 3);
5588            setflags = !InITBlock();
5589            shift_t = SRType_LSL;
5590            shift_n = 0;
5591            break;
5592        case eEncodingT2:
5593            Rd = Bits32(opcode, 11, 8);
5594            Rn = Bits32(opcode, 19, 16);
5595            Rm = Bits32(opcode, 3, 0);
5596            setflags = BitIsSet(opcode, 20);
5597            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5598            // if Rd == '1111' && S == '1' then SEE TST (register);
5599            if (Rd == 15 && setflags)
5600                return EmulateTSTReg(opcode, eEncodingT2);
5601            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5602                return false;
5603            break;
5604        case eEncodingA1:
5605            Rd = Bits32(opcode, 15, 12);
5606            Rn = Bits32(opcode, 19, 16);
5607            Rm = Bits32(opcode, 3, 0);
5608            setflags = BitIsSet(opcode, 20);
5609            shift_n = DecodeImmShiftARM(opcode, shift_t);
5610
5611            if (Rd == 15 && setflags)
5612                return EmulateSUBSPcLrEtc (opcode, encoding);
5613            break;
5614        default:
5615            return false;
5616        }
5617
5618        // Read the first operand.
5619        uint32_t val1 = ReadCoreReg(Rn, &success);
5620        if (!success)
5621            return false;
5622
5623        // Read the second operand.
5624        uint32_t val2 = ReadCoreReg(Rm, &success);
5625        if (!success)
5626            return false;
5627
5628        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5629        if (!success)
5630            return false;
5631        uint32_t result = val1 & shifted;
5632
5633        EmulateInstruction::Context context;
5634        context.type = EmulateInstruction::eContextImmediate;
5635        context.SetNoArgs ();
5636
5637        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5638            return false;
5639    }
5640    return true;
5641}
5642
5643// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5644// immediate value, and writes the result to the destination register.  It can optionally update the
5645// condition flags based on the result.
5646bool
5647EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5648{
5649#if 0
5650    // ARM pseudo code...
5651    if ConditionPassed() then
5652        EncodingSpecificOperations();
5653        result = R[n] AND NOT(imm32);
5654        if d == 15 then         // Can only occur for ARM encoding
5655            ALUWritePC(result); // setflags is always FALSE here
5656        else
5657            R[d] = result;
5658            if setflags then
5659                APSR.N = result<31>;
5660                APSR.Z = IsZeroBit(result);
5661                APSR.C = carry;
5662                // APSR.V unchanged
5663#endif
5664
5665    bool success = false;
5666
5667    if (ConditionPassed(opcode))
5668    {
5669        uint32_t Rd, Rn;
5670        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5671        bool setflags;
5672        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5673        switch (encoding)
5674        {
5675        case eEncodingT1:
5676            Rd = Bits32(opcode, 11, 8);
5677            Rn = Bits32(opcode, 19, 16);
5678            setflags = BitIsSet(opcode, 20);
5679            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5680            if (BadReg(Rd) || BadReg(Rn))
5681                return false;
5682            break;
5683        case eEncodingA1:
5684            Rd = Bits32(opcode, 15, 12);
5685            Rn = Bits32(opcode, 19, 16);
5686            setflags = BitIsSet(opcode, 20);
5687            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5688
5689            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5690            if (Rd == 15 && setflags)
5691                return EmulateSUBSPcLrEtc (opcode, encoding);
5692            break;
5693        default:
5694            return false;
5695        }
5696
5697        // Read the first operand.
5698        uint32_t val1 = ReadCoreReg(Rn, &success);
5699        if (!success)
5700            return false;
5701
5702        uint32_t result = val1 & ~imm32;
5703
5704        EmulateInstruction::Context context;
5705        context.type = EmulateInstruction::eContextImmediate;
5706        context.SetNoArgs ();
5707
5708        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5709            return false;
5710    }
5711    return true;
5712}
5713
5714// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5715// optionally-shifted register value, and writes the result to the destination register.
5716// It can optionally update the condition flags based on the result.
5717bool
5718EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5719{
5720#if 0
5721    // ARM pseudo code...
5722    if ConditionPassed() then
5723        EncodingSpecificOperations();
5724        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5725        result = R[n] AND NOT(shifted);
5726        if d == 15 then         // Can only occur for ARM encoding
5727            ALUWritePC(result); // setflags is always FALSE here
5728        else
5729            R[d] = result;
5730            if setflags then
5731                APSR.N = result<31>;
5732                APSR.Z = IsZeroBit(result);
5733                APSR.C = carry;
5734                // APSR.V unchanged
5735#endif
5736
5737    bool success = false;
5738
5739    if (ConditionPassed(opcode))
5740    {
5741        uint32_t Rd, Rn, Rm;
5742        ARM_ShifterType shift_t;
5743        uint32_t shift_n; // the shift applied to the value read from Rm
5744        bool setflags;
5745        uint32_t carry;
5746        switch (encoding)
5747        {
5748        case eEncodingT1:
5749            Rd = Rn = Bits32(opcode, 2, 0);
5750            Rm = Bits32(opcode, 5, 3);
5751            setflags = !InITBlock();
5752            shift_t = SRType_LSL;
5753            shift_n = 0;
5754            break;
5755        case eEncodingT2:
5756            Rd = Bits32(opcode, 11, 8);
5757            Rn = Bits32(opcode, 19, 16);
5758            Rm = Bits32(opcode, 3, 0);
5759            setflags = BitIsSet(opcode, 20);
5760            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5761            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5762                return false;
5763            break;
5764        case eEncodingA1:
5765            Rd = Bits32(opcode, 15, 12);
5766            Rn = Bits32(opcode, 19, 16);
5767            Rm = Bits32(opcode, 3, 0);
5768            setflags = BitIsSet(opcode, 20);
5769            shift_n = DecodeImmShiftARM(opcode, shift_t);
5770
5771            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5772            if (Rd == 15 && setflags)
5773                return EmulateSUBSPcLrEtc (opcode, encoding);
5774            break;
5775        default:
5776            return false;
5777        }
5778
5779        // Read the first operand.
5780        uint32_t val1 = ReadCoreReg(Rn, &success);
5781        if (!success)
5782            return false;
5783
5784        // Read the second operand.
5785        uint32_t val2 = ReadCoreReg(Rm, &success);
5786        if (!success)
5787            return false;
5788
5789        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5790        if (!success)
5791            return false;
5792        uint32_t result = val1 & ~shifted;
5793
5794        EmulateInstruction::Context context;
5795        context.type = EmulateInstruction::eContextImmediate;
5796        context.SetNoArgs ();
5797
5798        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5799            return false;
5800    }
5801    return true;
5802}
5803
5804// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5805// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5806bool
5807EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5808{
5809#if 0
5810    if ConditionPassed() then
5811        EncodingSpecificOperations();
5812        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5813        address = if index then offset_addr else R[n];
5814        data = MemU[address,4];
5815        if wback then R[n] = offset_addr;
5816        if t == 15 then
5817            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5818        elsif UnalignedSupport() || address<1:0> = '00' then
5819            R[t] = data;
5820        else // Can only apply before ARMv7
5821            R[t] = ROR(data, 8*UInt(address<1:0>));
5822#endif
5823
5824    bool success = false;
5825
5826    if (ConditionPassed(opcode))
5827    {
5828        const uint32_t addr_byte_size = GetAddressByteSize();
5829
5830        uint32_t t;
5831        uint32_t n;
5832        uint32_t imm32;
5833        bool index;
5834        bool add;
5835        bool wback;
5836
5837        switch (encoding)
5838        {
5839            case eEncodingA1:
5840                // if Rn == '1111' then SEE LDR (literal);
5841                // if P == '0' && W == '1' then SEE LDRT;
5842                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5843                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5844                t = Bits32 (opcode, 15, 12);
5845                n = Bits32 (opcode, 19, 16);
5846                imm32 = Bits32 (opcode, 11, 0);
5847
5848                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5849                index = BitIsSet (opcode, 24);
5850                add = BitIsSet (opcode, 23);
5851                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5852
5853                // if wback && n == t then UNPREDICTABLE;
5854                if (wback && (n == t))
5855                    return false;
5856
5857                break;
5858
5859            default:
5860                return false;
5861        }
5862
5863        addr_t address;
5864        addr_t offset_addr;
5865        addr_t base_address = ReadCoreReg (n, &success);
5866        if (!success)
5867            return false;
5868
5869        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5870        if (add)
5871            offset_addr = base_address + imm32;
5872        else
5873            offset_addr = base_address - imm32;
5874
5875        // address = if index then offset_addr else R[n];
5876        if (index)
5877            address = offset_addr;
5878        else
5879            address = base_address;
5880
5881        // data = MemU[address,4];
5882
5883        RegisterInfo base_reg;
5884        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5885
5886        EmulateInstruction::Context context;
5887        context.type = eContextRegisterLoad;
5888        context.SetRegisterPlusOffset (base_reg, address - base_address);
5889
5890        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5891        if (!success)
5892            return false;
5893
5894        // if wback then R[n] = offset_addr;
5895        if (wback)
5896        {
5897            context.type = eContextAdjustBaseRegister;
5898            context.SetAddress (offset_addr);
5899            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5900                return false;
5901        }
5902
5903        // if t == 15 then
5904        if (t == 15)
5905        {
5906            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5907            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5908            {
5909                // LoadWritePC (data);
5910                context.type = eContextRegisterLoad;
5911                context.SetRegisterPlusOffset (base_reg, address - base_address);
5912                LoadWritePC (context, data);
5913            }
5914            else
5915                  return false;
5916        }
5917        // elsif UnalignedSupport() || address<1:0> = '00' then
5918        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5919        {
5920            // R[t] = data;
5921            context.type = eContextRegisterLoad;
5922            context.SetRegisterPlusOffset (base_reg, address - base_address);
5923            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5924                return false;
5925        }
5926        // else // Can only apply before ARMv7
5927        else
5928        {
5929            // R[t] = ROR(data, 8*UInt(address<1:0>));
5930            data = ROR (data, Bits32 (address, 1, 0), &success);
5931            if (!success)
5932                return false;
5933            context.type = eContextRegisterLoad;
5934            context.SetImmediate (data);
5935            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5936                return false;
5937        }
5938
5939    }
5940    return true;
5941}
5942
5943// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5944// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5945bool
5946EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5947{
5948#if 0
5949    if ConditionPassed() then
5950        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5951        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5952        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5953        address = if index then offset_addr else R[n];
5954        data = MemU[address,4];
5955        if wback then R[n] = offset_addr;
5956        if t == 15 then
5957            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5958        elsif UnalignedSupport() || address<1:0> = '00' then
5959            R[t] = data;
5960        else // Can only apply before ARMv7
5961            if CurrentInstrSet() == InstrSet_ARM then
5962                R[t] = ROR(data, 8*UInt(address<1:0>));
5963            else
5964                R[t] = bits(32) UNKNOWN;
5965#endif
5966
5967    bool success = false;
5968
5969    if (ConditionPassed(opcode))
5970    {
5971        const uint32_t addr_byte_size = GetAddressByteSize();
5972
5973        uint32_t t;
5974        uint32_t n;
5975        uint32_t m;
5976        bool index;
5977        bool add;
5978        bool wback;
5979        ARM_ShifterType shift_t;
5980        uint32_t shift_n;
5981
5982        switch (encoding)
5983        {
5984            case eEncodingT1:
5985                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5986                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5987                t = Bits32 (opcode, 2, 0);
5988                n = Bits32 (opcode, 5, 3);
5989                m = Bits32 (opcode, 8, 6);
5990
5991                // index = TRUE; add = TRUE; wback = FALSE;
5992                index = true;
5993                add = true;
5994                wback = false;
5995
5996                // (shift_t, shift_n) = (SRType_LSL, 0);
5997                shift_t = SRType_LSL;
5998                shift_n = 0;
5999
6000                break;
6001
6002            case eEncodingT2:
6003                // if Rn == '1111' then SEE LDR (literal);
6004                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6005                t = Bits32 (opcode, 15, 12);
6006                n = Bits32 (opcode, 19, 16);
6007                m = Bits32 (opcode, 3, 0);
6008
6009                // index = TRUE; add = TRUE; wback = FALSE;
6010                index = true;
6011                add = true;
6012                wback = false;
6013
6014                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6015                shift_t = SRType_LSL;
6016                shift_n = Bits32 (opcode, 5, 4);
6017
6018                // if BadReg(m) then UNPREDICTABLE;
6019                if (BadReg (m))
6020                    return false;
6021
6022                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6023                if ((t == 15) && InITBlock() && !LastInITBlock())
6024                    return false;
6025
6026                break;
6027
6028            case eEncodingA1:
6029            {
6030                // if P == '0' && W == '1' then SEE LDRT;
6031                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6032                t = Bits32 (opcode, 15, 12);
6033                n = Bits32 (opcode, 19, 16);
6034                m = Bits32 (opcode, 3, 0);
6035
6036                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6037                index = BitIsSet (opcode, 24);
6038                add = BitIsSet (opcode, 23);
6039                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6040
6041                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6042                uint32_t type = Bits32 (opcode, 6, 5);
6043                uint32_t imm5 = Bits32 (opcode, 11, 7);
6044                shift_n = DecodeImmShift (type, imm5, shift_t);
6045
6046                // if m == 15 then UNPREDICTABLE;
6047                if (m == 15)
6048                    return false;
6049
6050                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6051                if (wback && ((n == 15) || (n == t)))
6052                    return false;
6053            }
6054                break;
6055
6056
6057            default:
6058                return false;
6059        }
6060
6061        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6062        if (!success)
6063            return false;
6064
6065        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6066        if (!success)
6067            return false;
6068
6069        addr_t offset_addr;
6070        addr_t address;
6071
6072        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6073        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6074        if (!success)
6075            return false;
6076
6077        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6078        if (add)
6079            offset_addr = Rn + offset;
6080        else
6081            offset_addr = Rn - offset;
6082
6083        // address = if index then offset_addr else R[n];
6084            if (index)
6085                address = offset_addr;
6086            else
6087                address = Rn;
6088
6089        // data = MemU[address,4];
6090        RegisterInfo base_reg;
6091        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6092
6093        EmulateInstruction::Context context;
6094        context.type = eContextRegisterLoad;
6095        context.SetRegisterPlusOffset (base_reg, address - Rn);
6096
6097        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6098        if (!success)
6099            return false;
6100
6101        // if wback then R[n] = offset_addr;
6102        if (wback)
6103        {
6104            context.type = eContextAdjustBaseRegister;
6105            context.SetAddress (offset_addr);
6106            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6107                return false;
6108        }
6109
6110        // if t == 15 then
6111        if (t == 15)
6112        {
6113            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6114            if (BitIsClear (address, 1) && BitIsClear (address, 0))
6115            {
6116                context.type = eContextRegisterLoad;
6117                context.SetRegisterPlusOffset (base_reg, address - Rn);
6118                LoadWritePC (context, data);
6119            }
6120            else
6121                return false;
6122        }
6123        // elsif UnalignedSupport() || address<1:0> = '00' then
6124        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6125        {
6126            // R[t] = data;
6127            context.type = eContextRegisterLoad;
6128            context.SetRegisterPlusOffset (base_reg, address - Rn);
6129            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6130                return false;
6131        }
6132        else // Can only apply before ARMv7
6133        {
6134            // if CurrentInstrSet() == InstrSet_ARM then
6135            if (CurrentInstrSet () == eModeARM)
6136            {
6137                // R[t] = ROR(data, 8*UInt(address<1:0>));
6138                data = ROR (data, Bits32 (address, 1, 0), &success);
6139                if (!success)
6140                    return false;
6141                context.type = eContextRegisterLoad;
6142                context.SetImmediate (data);
6143                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6144                    return false;
6145            }
6146            else
6147            {
6148                // R[t] = bits(32) UNKNOWN;
6149                WriteBits32Unknown (t);
6150            }
6151        }
6152    }
6153    return true;
6154}
6155
6156// LDRB (immediate, Thumb)
6157bool
6158EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6159{
6160#if 0
6161    if ConditionPassed() then
6162        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6163        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6164        address = if index then offset_addr else R[n];
6165        R[t] = ZeroExtend(MemU[address,1], 32);
6166        if wback then R[n] = offset_addr;
6167#endif
6168
6169    bool success = false;
6170
6171    if (ConditionPassed(opcode))
6172    {
6173        uint32_t t;
6174        uint32_t n;
6175        uint32_t imm32;
6176        bool index;
6177        bool add;
6178        bool wback;
6179
6180        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6181        switch (encoding)
6182        {
6183            case eEncodingT1:
6184                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6185                t = Bits32 (opcode, 2, 0);
6186                n = Bits32 (opcode, 5, 3);
6187                imm32 = Bits32 (opcode, 10, 6);
6188
6189                // index = TRUE; add = TRUE; wback = FALSE;
6190                index = true;
6191                add = true;
6192                wback= false;
6193
6194                break;
6195
6196            case eEncodingT2:
6197                // if Rt == '1111' then SEE PLD;
6198                // if Rn == '1111' then SEE LDRB (literal);
6199                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6200                t = Bits32 (opcode, 15, 12);
6201                n = Bits32 (opcode, 19, 16);
6202                imm32 = Bits32 (opcode, 11, 0);
6203
6204                // index = TRUE; add = TRUE; wback = FALSE;
6205                index = true;
6206                add = true;
6207                wback = false;
6208
6209                // if t == 13 then UNPREDICTABLE;
6210                if (t == 13)
6211                    return false;
6212
6213                break;
6214
6215            case eEncodingT3:
6216                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6217                // if Rn == '1111' then SEE LDRB (literal);
6218                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6219                // if P == '0' && W == '0' then UNDEFINED;
6220                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6221                    return false;
6222
6223                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6224                t = Bits32 (opcode, 15, 12);
6225                n = Bits32 (opcode, 19, 16);
6226                imm32 = Bits32 (opcode, 7, 0);
6227
6228                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6229                index = BitIsSet (opcode, 10);
6230                add = BitIsSet (opcode, 9);
6231                wback = BitIsSet (opcode, 8);
6232
6233                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6234                if (BadReg (t) || (wback && (n == t)))
6235                    return false;
6236
6237                break;
6238
6239            default:
6240                return false;
6241        }
6242
6243        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6244        if (!success)
6245            return false;
6246
6247        addr_t address;
6248        addr_t offset_addr;
6249
6250        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6251        if (add)
6252            offset_addr = Rn + imm32;
6253        else
6254            offset_addr = Rn - imm32;
6255
6256        // address = if index then offset_addr else R[n];
6257        if (index)
6258            address = offset_addr;
6259        else
6260            address = Rn;
6261
6262        // R[t] = ZeroExtend(MemU[address,1], 32);
6263        RegisterInfo base_reg;
6264        RegisterInfo data_reg;
6265        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6266        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6267
6268        EmulateInstruction::Context context;
6269        context.type = eContextRegisterLoad;
6270        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6271
6272        uint64_t data = MemURead (context, address, 1, 0, &success);
6273        if (!success)
6274            return false;
6275
6276        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6277            return false;
6278
6279        // if wback then R[n] = offset_addr;
6280        if (wback)
6281        {
6282            context.type = eContextAdjustBaseRegister;
6283            context.SetAddress (offset_addr);
6284            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6285                return false;
6286        }
6287    }
6288    return true;
6289}
6290
6291// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6292// zero-extends it to form a 32-bit word and writes it to a register.
6293bool
6294EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6295{
6296#if 0
6297    if ConditionPassed() then
6298        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6299        base = Align(PC,4);
6300        address = if add then (base + imm32) else (base - imm32);
6301        R[t] = ZeroExtend(MemU[address,1], 32);
6302#endif
6303
6304    bool success = false;
6305
6306    if (ConditionPassed(opcode))
6307    {
6308        uint32_t t;
6309        uint32_t imm32;
6310        bool add;
6311        switch (encoding)
6312        {
6313            case eEncodingT1:
6314                // if Rt == '1111' then SEE PLD;
6315                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6316                t = Bits32 (opcode, 15, 12);
6317                imm32 = Bits32 (opcode, 11, 0);
6318                add = BitIsSet (opcode, 23);
6319
6320                // if t == 13 then UNPREDICTABLE;
6321                if (t == 13)
6322                    return false;
6323
6324                break;
6325
6326            case eEncodingA1:
6327                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6328                t = Bits32 (opcode, 15, 12);
6329                imm32 = Bits32 (opcode, 11, 0);
6330                add = BitIsSet (opcode, 23);
6331
6332                // if t == 15 then UNPREDICTABLE;
6333                if (t == 15)
6334                    return false;
6335                break;
6336
6337            default:
6338                return false;
6339        }
6340
6341        // base = Align(PC,4);
6342        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6343        if (!success)
6344            return false;
6345
6346        uint32_t base = AlignPC (pc_val);
6347
6348        addr_t address;
6349        // address = if add then (base + imm32) else (base - imm32);
6350        if (add)
6351            address = base + imm32;
6352        else
6353            address = base - imm32;
6354
6355        // R[t] = ZeroExtend(MemU[address,1], 32);
6356        EmulateInstruction::Context context;
6357        context.type = eContextRelativeBranchImmediate;
6358        context.SetImmediate (address - base);
6359
6360        uint64_t data = MemURead (context, address, 1, 0, &success);
6361        if (!success)
6362            return false;
6363
6364        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6365            return false;
6366    }
6367    return true;
6368}
6369
6370// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6371// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6372// optionally be shifted.
6373bool
6374EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6375{
6376#if 0
6377    if ConditionPassed() then
6378        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6379        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6380        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6381        address = if index then offset_addr else R[n];
6382        R[t] = ZeroExtend(MemU[address,1],32);
6383        if wback then R[n] = offset_addr;
6384#endif
6385
6386    bool success = false;
6387
6388    if (ConditionPassed(opcode))
6389    {
6390        uint32_t t;
6391        uint32_t n;
6392        uint32_t m;
6393        bool index;
6394        bool add;
6395        bool wback;
6396        ARM_ShifterType shift_t;
6397        uint32_t shift_n;
6398
6399        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6400        switch (encoding)
6401        {
6402            case eEncodingT1:
6403                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6404                t = Bits32 (opcode, 2, 0);
6405                n = Bits32 (opcode, 5, 3);
6406                m = Bits32 (opcode, 8, 6);
6407
6408                // index = TRUE; add = TRUE; wback = FALSE;
6409                index = true;
6410                add = true;
6411                wback = false;
6412
6413                // (shift_t, shift_n) = (SRType_LSL, 0);
6414                shift_t = SRType_LSL;
6415                shift_n = 0;
6416                break;
6417
6418            case eEncodingT2:
6419                // if Rt == '1111' then SEE PLD;
6420                // if Rn == '1111' then SEE LDRB (literal);
6421                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6422                t = Bits32 (opcode, 15, 12);
6423                n = Bits32 (opcode, 19, 16);
6424                m = Bits32 (opcode, 3, 0);
6425
6426                // index = TRUE; add = TRUE; wback = FALSE;
6427                index = true;
6428                add = true;
6429                wback = false;
6430
6431                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6432                shift_t = SRType_LSL;
6433                shift_n = Bits32 (opcode, 5, 4);
6434
6435                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6436                if ((t == 13) || BadReg (m))
6437                    return false;
6438                break;
6439
6440            case eEncodingA1:
6441            {
6442                // if P == '0' && W == '1' then SEE LDRBT;
6443                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6444                t = Bits32 (opcode, 15, 12);
6445                n = Bits32 (opcode, 19, 16);
6446                m = Bits32 (opcode, 3, 0);
6447
6448                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6449                index = BitIsSet (opcode, 24);
6450                add = BitIsSet (opcode, 23);
6451                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6452
6453                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6454                uint32_t type = Bits32 (opcode, 6, 5);
6455                uint32_t imm5 = Bits32 (opcode, 11, 7);
6456                shift_n = DecodeImmShift (type, imm5, shift_t);
6457
6458                // if t == 15 || m == 15 then UNPREDICTABLE;
6459                if ((t == 15) || (m == 15))
6460                    return false;
6461
6462                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6463                if (wback && ((n == 15) || (n == t)))
6464                    return false;
6465            }
6466                break;
6467
6468            default:
6469                return false;
6470        }
6471
6472        addr_t offset_addr;
6473        addr_t address;
6474
6475        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6476        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6477        if (!success)
6478            return false;
6479
6480        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6481        if (!success)
6482            return false;
6483
6484        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6485        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6486        if (!success)
6487            return false;
6488
6489        if (add)
6490            offset_addr = Rn + offset;
6491        else
6492            offset_addr = Rn - offset;
6493
6494        // address = if index then offset_addr else R[n];
6495        if (index)
6496            address = offset_addr;
6497        else
6498            address = Rn;
6499
6500        // R[t] = ZeroExtend(MemU[address,1],32);
6501        RegisterInfo base_reg;
6502        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6503
6504        EmulateInstruction::Context context;
6505        context.type = eContextRegisterLoad;
6506        context.SetRegisterPlusOffset (base_reg, address - Rn);
6507
6508        uint64_t data = MemURead (context, address, 1, 0, &success);
6509        if (!success)
6510            return false;
6511
6512        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6513            return false;
6514
6515        // if wback then R[n] = offset_addr;
6516        if (wback)
6517        {
6518            context.type = eContextAdjustBaseRegister;
6519            context.SetAddress (offset_addr);
6520            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6521                return false;
6522        }
6523    }
6524    return true;
6525}
6526
6527// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6528// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6529// post-indexed, or pre-indexed addressing.
6530bool
6531EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6532{
6533#if 0
6534    if ConditionPassed() then
6535        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6536        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6537        address = if index then offset_addr else R[n];
6538        data = MemU[address,2];
6539        if wback then R[n] = offset_addr;
6540        if UnalignedSupport() || address<0> = '0' then
6541            R[t] = ZeroExtend(data, 32);
6542        else // Can only apply before ARMv7
6543            R[t] = bits(32) UNKNOWN;
6544#endif
6545
6546
6547    bool success = false;
6548
6549    if (ConditionPassed(opcode))
6550    {
6551        uint32_t t;
6552        uint32_t n;
6553        uint32_t imm32;
6554        bool index;
6555        bool add;
6556        bool wback;
6557
6558        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6559        switch (encoding)
6560        {
6561            case eEncodingT1:
6562                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6563                t = Bits32 (opcode, 2, 0);
6564                n = Bits32 (opcode, 5, 3);
6565                imm32 = Bits32 (opcode, 10, 6) << 1;
6566
6567                // index = TRUE; add = TRUE; wback = FALSE;
6568                index = true;
6569                add = true;
6570                wback = false;
6571
6572                break;
6573
6574            case eEncodingT2:
6575                // if Rt == '1111' then SEE "Unallocated memory hints";
6576                // if Rn == '1111' then SEE LDRH (literal);
6577                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6578                t = Bits32 (opcode, 15, 12);
6579                n = Bits32 (opcode, 19, 16);
6580                imm32 = Bits32 (opcode, 11, 0);
6581
6582                // index = TRUE; add = TRUE; wback = FALSE;
6583                index = true;
6584                add = true;
6585                wback = false;
6586
6587                // if t == 13 then UNPREDICTABLE;
6588                if (t == 13)
6589                    return false;
6590                break;
6591
6592            case eEncodingT3:
6593                // if Rn == '1111' then SEE LDRH (literal);
6594                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6595                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6596                // if P == '0' && W == '0' then UNDEFINED;
6597                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6598                    return false;
6599
6600                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6601                t = Bits32 (opcode, 15, 12);
6602                n = Bits32 (opcode, 19, 16);
6603                imm32 = Bits32 (opcode, 7, 0);
6604
6605                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6606                index = BitIsSet (opcode, 10);
6607                add = BitIsSet (opcode, 9);
6608                wback = BitIsSet (opcode, 8);
6609
6610                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6611                if (BadReg (t) || (wback && (n == t)))
6612                    return false;
6613                break;
6614
6615            default:
6616                return false;
6617        }
6618
6619        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6620        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6621        if (!success)
6622            return false;
6623
6624        addr_t offset_addr;
6625        addr_t address;
6626
6627        if (add)
6628            offset_addr = Rn + imm32;
6629        else
6630            offset_addr = Rn - imm32;
6631
6632        // address = if index then offset_addr else R[n];
6633        if (index)
6634            address = offset_addr;
6635        else
6636            address = Rn;
6637
6638        // data = MemU[address,2];
6639        RegisterInfo base_reg;
6640        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6641
6642        EmulateInstruction::Context context;
6643        context.type = eContextRegisterLoad;
6644        context.SetRegisterPlusOffset (base_reg, address - Rn);
6645
6646        uint64_t data = MemURead (context, address, 2, 0, &success);
6647        if (!success)
6648            return false;
6649
6650        // if wback then R[n] = offset_addr;
6651        if (wback)
6652        {
6653            context.type = eContextAdjustBaseRegister;
6654            context.SetAddress (offset_addr);
6655            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6656                return false;
6657        }
6658
6659        // if UnalignedSupport() || address<0> = '0' then
6660        if (UnalignedSupport () || BitIsClear (address, 0))
6661        {
6662            // R[t] = ZeroExtend(data, 32);
6663            context.type = eContextRegisterLoad;
6664            context.SetRegisterPlusOffset (base_reg, address - Rn);
6665            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6666                return false;
6667        }
6668        else // Can only apply before ARMv7
6669        {
6670            // R[t] = bits(32) UNKNOWN;
6671            WriteBits32Unknown (t);
6672        }
6673    }
6674    return true;
6675}
6676
6677// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6678// zero-extends it to form a 32-bit word, and writes it to a register.
6679bool
6680EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6681{
6682#if 0
6683    if ConditionPassed() then
6684        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6685        base = Align(PC,4);
6686        address = if add then (base + imm32) else (base - imm32);
6687        data = MemU[address,2];
6688        if UnalignedSupport() || address<0> = '0' then
6689            R[t] = ZeroExtend(data, 32);
6690        else // Can only apply before ARMv7
6691            R[t] = bits(32) UNKNOWN;
6692#endif
6693
6694    bool success = false;
6695
6696    if (ConditionPassed(opcode))
6697    {
6698        uint32_t t;
6699        uint32_t imm32;
6700        bool add;
6701
6702        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6703        switch (encoding)
6704        {
6705            case eEncodingT1:
6706                // if Rt == '1111' then SEE "Unallocated memory hints";
6707                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6708                t = Bits32 (opcode, 15, 12);
6709                imm32 = Bits32 (opcode, 11, 0);
6710                add = BitIsSet (opcode, 23);
6711
6712                // if t == 13 then UNPREDICTABLE;
6713                if (t == 13)
6714                    return false;
6715
6716                break;
6717
6718            case eEncodingA1:
6719            {
6720                uint32_t imm4H = Bits32 (opcode, 11, 8);
6721                uint32_t imm4L = Bits32 (opcode, 3, 0);
6722
6723                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6724                t = Bits32 (opcode, 15, 12);
6725                imm32 = (imm4H << 4) | imm4L;
6726                add = BitIsSet (opcode, 23);
6727
6728                // if t == 15 then UNPREDICTABLE;
6729                if (t == 15)
6730                    return false;
6731                break;
6732            }
6733
6734            default:
6735                return false;
6736        }
6737
6738        // base = Align(PC,4);
6739        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6740        if (!success)
6741            return false;
6742
6743        addr_t base = AlignPC (pc_value);
6744        addr_t address;
6745
6746        // address = if add then (base + imm32) else (base - imm32);
6747        if (add)
6748            address = base + imm32;
6749        else
6750            address = base - imm32;
6751
6752        // data = MemU[address,2];
6753        RegisterInfo base_reg;
6754        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6755
6756        EmulateInstruction::Context context;
6757        context.type = eContextRegisterLoad;
6758        context.SetRegisterPlusOffset (base_reg, address - base);
6759
6760        uint64_t data = MemURead (context, address, 2, 0, &success);
6761        if (!success)
6762            return false;
6763
6764
6765        // if UnalignedSupport() || address<0> = '0' then
6766        if (UnalignedSupport () || BitIsClear (address, 0))
6767        {
6768            // R[t] = ZeroExtend(data, 32);
6769            context.type = eContextRegisterLoad;
6770            context.SetRegisterPlusOffset (base_reg, address - base);
6771            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6772                return false;
6773
6774        }
6775        else // Can only apply before ARMv7
6776        {
6777            // R[t] = bits(32) UNKNOWN;
6778            WriteBits32Unknown (t);
6779        }
6780    }
6781    return true;
6782}
6783
6784// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6785// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6786// be shifted left by 0, 1, 2, or 3 bits.
6787bool
6788EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6789{
6790#if 0
6791    if ConditionPassed() then
6792        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6793        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6794        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6795        address = if index then offset_addr else R[n];
6796        data = MemU[address,2];
6797        if wback then R[n] = offset_addr;
6798        if UnalignedSupport() || address<0> = '0' then
6799            R[t] = ZeroExtend(data, 32);
6800        else // Can only apply before ARMv7
6801            R[t] = bits(32) UNKNOWN;
6802#endif
6803
6804    bool success = false;
6805
6806    if (ConditionPassed(opcode))
6807    {
6808        uint32_t t;
6809        uint32_t n;
6810        uint32_t m;
6811        bool index;
6812        bool add;
6813        bool wback;
6814        ARM_ShifterType shift_t;
6815        uint32_t shift_n;
6816
6817        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6818        switch (encoding)
6819        {
6820            case eEncodingT1:
6821                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6822                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6823                t = Bits32 (opcode, 2, 0);
6824                n = Bits32 (opcode, 5, 3);
6825                m = Bits32 (opcode, 8, 6);
6826
6827                // index = TRUE; add = TRUE; wback = FALSE;
6828                index = true;
6829                add = true;
6830                wback = false;
6831
6832                // (shift_t, shift_n) = (SRType_LSL, 0);
6833                shift_t = SRType_LSL;
6834                shift_n = 0;
6835
6836                break;
6837
6838            case eEncodingT2:
6839                // if Rn == '1111' then SEE LDRH (literal);
6840                // if Rt == '1111' then SEE "Unallocated memory hints";
6841                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6842                t = Bits32 (opcode, 15, 12);
6843                n = Bits32 (opcode, 19, 16);
6844                m = Bits32 (opcode, 3, 0);
6845
6846                // index = TRUE; add = TRUE; wback = FALSE;
6847                index = true;
6848                add = true;
6849                wback = false;
6850
6851                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6852                shift_t = SRType_LSL;
6853                shift_n = Bits32 (opcode, 5, 4);
6854
6855                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6856                if ((t == 13) || BadReg (m))
6857                    return false;
6858                break;
6859
6860            case eEncodingA1:
6861                // if P == '0' && W == '1' then SEE LDRHT;
6862                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6863                t = Bits32 (opcode, 15, 12);
6864                n = Bits32 (opcode, 19, 16);
6865                m = Bits32 (opcode, 3, 0);
6866
6867                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6868                index = BitIsSet (opcode, 24);
6869                add = BitIsSet (opcode, 23);
6870                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6871
6872                // (shift_t, shift_n) = (SRType_LSL, 0);
6873                shift_t = SRType_LSL;
6874                shift_n = 0;
6875
6876                // if t == 15 || m == 15 then UNPREDICTABLE;
6877                if ((t == 15) || (m == 15))
6878                    return false;
6879
6880                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6881                if (wback && ((n == 15) || (n == t)))
6882                    return false;
6883
6884                break;
6885
6886            default:
6887                return false;
6888        }
6889
6890        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6891
6892        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6893        if (!success)
6894            return false;
6895
6896        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6897        if (!success)
6898            return false;
6899
6900        addr_t offset_addr;
6901        addr_t address;
6902
6903        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6904        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6905        if (!success)
6906            return false;
6907
6908        if (add)
6909            offset_addr = Rn + offset;
6910        else
6911            offset_addr = Rn - offset;
6912
6913        // address = if index then offset_addr else R[n];
6914        if (index)
6915            address = offset_addr;
6916        else
6917            address = Rn;
6918
6919        // data = MemU[address,2];
6920        RegisterInfo base_reg;
6921        RegisterInfo offset_reg;
6922        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6923        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6924
6925        EmulateInstruction::Context context;
6926        context.type = eContextRegisterLoad;
6927        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6928        uint64_t data = MemURead (context, address, 2, 0, &success);
6929        if (!success)
6930            return false;
6931
6932        // if wback then R[n] = offset_addr;
6933        if (wback)
6934        {
6935            context.type = eContextAdjustBaseRegister;
6936            context.SetAddress (offset_addr);
6937            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6938                return false;
6939        }
6940
6941        // if UnalignedSupport() || address<0> = '0' then
6942        if (UnalignedSupport() || BitIsClear (address, 0))
6943        {
6944            // R[t] = ZeroExtend(data, 32);
6945            context.type = eContextRegisterLoad;
6946            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6947            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6948                return false;
6949        }
6950        else // Can only apply before ARMv7
6951        {
6952            // R[t] = bits(32) UNKNOWN;
6953            WriteBits32Unknown (t);
6954        }
6955    }
6956    return true;
6957}
6958
6959// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6960// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6961// or pre-indexed addressing.
6962bool
6963EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6964{
6965#if 0
6966    if ConditionPassed() then
6967        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6968        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6969        address = if index then offset_addr else R[n];
6970        R[t] = SignExtend(MemU[address,1], 32);
6971        if wback then R[n] = offset_addr;
6972#endif
6973
6974    bool success = false;
6975
6976    if (ConditionPassed(opcode))
6977    {
6978        uint32_t t;
6979        uint32_t n;
6980        uint32_t imm32;
6981        bool index;
6982        bool add;
6983        bool wback;
6984
6985        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6986        switch (encoding)
6987        {
6988            case eEncodingT1:
6989                // if Rt == '1111' then SEE PLI;
6990                // if Rn == '1111' then SEE LDRSB (literal);
6991                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6992                t = Bits32 (opcode, 15, 12);
6993                n = Bits32 (opcode, 19, 16);
6994                imm32 = Bits32 (opcode, 11, 0);
6995
6996                // index = TRUE; add = TRUE; wback = FALSE;
6997                index = true;
6998                add = true;
6999                wback = false;
7000
7001                // if t == 13 then UNPREDICTABLE;
7002                if (t == 13)
7003                    return false;
7004
7005                break;
7006
7007            case eEncodingT2:
7008                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7009                // if Rn == '1111' then SEE LDRSB (literal);
7010                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7011                // if P == '0' && W == '0' then UNDEFINED;
7012                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7013                    return false;
7014
7015                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7016                t = Bits32 (opcode, 15, 12);
7017                n = Bits32 (opcode, 19, 16);
7018                imm32 = Bits32 (opcode, 7, 0);
7019
7020                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7021                index = BitIsSet (opcode, 10);
7022                add = BitIsSet (opcode, 9);
7023                wback = BitIsSet (opcode, 8);
7024
7025                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7026                  if (((t == 13) || ((t == 15)
7027                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7028                      || (wback && (n == t)))
7029                    return false;
7030
7031                break;
7032
7033            case eEncodingA1:
7034            {
7035                // if Rn == '1111' then SEE LDRSB (literal);
7036                // if P == '0' && W == '1' then SEE LDRSBT;
7037                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7038                t = Bits32 (opcode, 15, 12);
7039                n = Bits32 (opcode, 19, 16);
7040
7041                uint32_t imm4H = Bits32 (opcode, 11, 8);
7042                uint32_t imm4L = Bits32 (opcode, 3, 0);
7043                imm32 = (imm4H << 4) | imm4L;
7044
7045                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7046                index = BitIsSet (opcode, 24);
7047                add = BitIsSet (opcode, 23);
7048                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7049
7050                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7051                if ((t == 15) || (wback && (n == t)))
7052                    return false;
7053
7054                break;
7055            }
7056
7057            default:
7058                return false;
7059        }
7060
7061        uint64_t Rn = ReadCoreReg (n, &success);
7062        if (!success)
7063            return false;
7064
7065        addr_t offset_addr;
7066        addr_t address;
7067
7068        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7069        if (add)
7070            offset_addr = Rn + imm32;
7071        else
7072            offset_addr = Rn - imm32;
7073
7074        // address = if index then offset_addr else R[n];
7075        if (index)
7076            address = offset_addr;
7077        else
7078            address = Rn;
7079
7080        // R[t] = SignExtend(MemU[address,1], 32);
7081        RegisterInfo base_reg;
7082        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7083
7084        EmulateInstruction::Context context;
7085        context.type = eContextRegisterLoad;
7086        context.SetRegisterPlusOffset (base_reg, address - Rn);
7087
7088        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7089        if (!success)
7090            return false;
7091
7092        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7093        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7094            return false;
7095
7096        // if wback then R[n] = offset_addr;
7097        if (wback)
7098        {
7099            context.type = eContextAdjustBaseRegister;
7100            context.SetAddress (offset_addr);
7101            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7102                return false;
7103        }
7104    }
7105
7106    return true;
7107}
7108
7109// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7110// sign-extends it to form a 32-bit word, and writes tit to a register.
7111bool
7112EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7113{
7114#if 0
7115    if ConditionPassed() then
7116        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7117        base = Align(PC,4);
7118        address = if add then (base + imm32) else (base - imm32);
7119        R[t] = SignExtend(MemU[address,1], 32);
7120#endif
7121
7122    bool success = false;
7123
7124    if (ConditionPassed(opcode))
7125    {
7126        uint32_t t;
7127        uint32_t imm32;
7128        bool add;
7129
7130        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7131        switch (encoding)
7132        {
7133            case eEncodingT1:
7134                // if Rt == '1111' then SEE PLI;
7135                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7136                t = Bits32 (opcode, 15, 12);
7137                imm32 = Bits32 (opcode, 11, 0);
7138                add = BitIsSet (opcode, 23);
7139
7140                // if t == 13 then UNPREDICTABLE;
7141                if (t == 13)
7142                    return false;
7143
7144                break;
7145
7146            case eEncodingA1:
7147            {
7148                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7149                t = Bits32 (opcode, 15, 12);
7150                uint32_t imm4H = Bits32 (opcode, 11, 8);
7151                uint32_t imm4L = Bits32 (opcode, 3, 0);
7152                imm32 = (imm4H << 4) | imm4L;
7153                add = BitIsSet (opcode, 23);
7154
7155                // if t == 15 then UNPREDICTABLE;
7156                if (t == 15)
7157                    return false;
7158
7159                break;
7160            }
7161
7162            default:
7163                return false;
7164        }
7165
7166        // base = Align(PC,4);
7167        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7168        if (!success)
7169            return false;
7170        uint64_t base = AlignPC (pc_value);
7171
7172        // address = if add then (base + imm32) else (base - imm32);
7173        addr_t address;
7174        if (add)
7175            address = base + imm32;
7176        else
7177            address = base - imm32;
7178
7179        // R[t] = SignExtend(MemU[address,1], 32);
7180        RegisterInfo base_reg;
7181        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7182
7183        EmulateInstruction::Context context;
7184        context.type = eContextRegisterLoad;
7185        context.SetRegisterPlusOffset (base_reg, address - base);
7186
7187        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7188        if (!success)
7189            return false;
7190
7191        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7192        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7193            return false;
7194    }
7195    return true;
7196}
7197
7198// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7199// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7200// shifted left by 0, 1, 2, or 3 bits.
7201bool
7202EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7203{
7204#if 0
7205    if ConditionPassed() then
7206        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7207        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7208        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7209        address = if index then offset_addr else R[n];
7210        R[t] = SignExtend(MemU[address,1], 32);
7211        if wback then R[n] = offset_addr;
7212#endif
7213
7214    bool success = false;
7215
7216    if (ConditionPassed(opcode))
7217    {
7218        uint32_t t;
7219        uint32_t n;
7220        uint32_t m;
7221        bool index;
7222        bool add;
7223        bool wback;
7224        ARM_ShifterType shift_t;
7225        uint32_t shift_n;
7226
7227        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7228        switch (encoding)
7229        {
7230            case eEncodingT1:
7231                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7232                t = Bits32 (opcode, 2, 0);
7233                n = Bits32 (opcode, 5, 3);
7234                m = Bits32 (opcode, 8, 6);
7235
7236                // index = TRUE; add = TRUE; wback = FALSE;
7237                index = true;
7238                add = true;
7239                wback = false;
7240
7241                // (shift_t, shift_n) = (SRType_LSL, 0);
7242                shift_t = SRType_LSL;
7243                shift_n = 0;
7244
7245                break;
7246
7247            case eEncodingT2:
7248                // if Rt == '1111' then SEE PLI;
7249                // if Rn == '1111' then SEE LDRSB (literal);
7250                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7251                t = Bits32 (opcode, 15, 12);
7252                n = Bits32 (opcode, 19, 16);
7253                m = Bits32 (opcode, 3, 0);
7254
7255                // index = TRUE; add = TRUE; wback = FALSE;
7256                index = true;
7257                add = true;
7258                wback = false;
7259
7260                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7261                shift_t = SRType_LSL;
7262                shift_n = Bits32 (opcode, 5, 4);
7263
7264                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7265                if ((t == 13) || BadReg (m))
7266                    return false;
7267                break;
7268
7269            case eEncodingA1:
7270                // if P == '0' && W == '1' then SEE LDRSBT;
7271                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7272                t = Bits32 (opcode, 15, 12);
7273                n = Bits32 (opcode, 19, 16);
7274                m = Bits32 (opcode, 3, 0);
7275
7276                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7277                index = BitIsSet (opcode, 24);
7278                add = BitIsSet (opcode, 23);
7279                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7280
7281                // (shift_t, shift_n) = (SRType_LSL, 0);
7282                shift_t = SRType_LSL;
7283                shift_n = 0;
7284
7285                // if t == 15 || m == 15 then UNPREDICTABLE;
7286                if ((t == 15) || (m == 15))
7287                    return false;
7288
7289                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7290                if (wback && ((n == 15) || (n == t)))
7291                    return false;
7292                break;
7293
7294            default:
7295                return false;
7296        }
7297
7298        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7299        if (!success)
7300            return false;
7301
7302        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7303        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7304        if (!success)
7305            return false;
7306
7307        addr_t offset_addr;
7308        addr_t address;
7309
7310        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7311        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7312        if (!success)
7313            return false;
7314
7315        if (add)
7316            offset_addr = Rn + offset;
7317        else
7318            offset_addr = Rn - offset;
7319
7320        // address = if index then offset_addr else R[n];
7321        if (index)
7322            address = offset_addr;
7323        else
7324            address = Rn;
7325
7326        // R[t] = SignExtend(MemU[address,1], 32);
7327        RegisterInfo base_reg;
7328        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7329        RegisterInfo offset_reg;
7330        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7331
7332        EmulateInstruction::Context context;
7333        context.type = eContextRegisterLoad;
7334        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7335
7336        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7337        if (!success)
7338            return false;
7339
7340        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7341        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7342            return false;
7343
7344        // if wback then R[n] = offset_addr;
7345        if (wback)
7346        {
7347            context.type = eContextAdjustBaseRegister;
7348            context.SetAddress (offset_addr);
7349            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7350                return false;
7351        }
7352    }
7353    return true;
7354}
7355
7356// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7357// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7358// pre-indexed addressing.
7359bool
7360EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7361{
7362#if 0
7363    if ConditionPassed() then
7364        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7365        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7366        address = if index then offset_addr else R[n];
7367        data = MemU[address,2];
7368        if wback then R[n] = offset_addr;
7369        if UnalignedSupport() || address<0> = '0' then
7370            R[t] = SignExtend(data, 32);
7371        else // Can only apply before ARMv7
7372            R[t] = bits(32) UNKNOWN;
7373#endif
7374
7375    bool success = false;
7376
7377    if (ConditionPassed(opcode))
7378    {
7379        uint32_t t;
7380        uint32_t n;
7381        uint32_t imm32;
7382        bool index;
7383        bool add;
7384        bool wback;
7385
7386        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7387        switch (encoding)
7388        {
7389            case eEncodingT1:
7390                // if Rn == '1111' then SEE LDRSH (literal);
7391                // if Rt == '1111' then SEE "Unallocated memory hints";
7392                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7393                t = Bits32 (opcode, 15, 12);
7394                n = Bits32 (opcode, 19, 16);
7395                imm32 = Bits32 (opcode, 11, 0);
7396
7397                // index = TRUE; add = TRUE; wback = FALSE;
7398                index = true;
7399                add = true;
7400                wback = false;
7401
7402                // if t == 13 then UNPREDICTABLE;
7403                if (t == 13)
7404                    return false;
7405
7406                break;
7407
7408            case eEncodingT2:
7409                // if Rn == '1111' then SEE LDRSH (literal);
7410                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7411                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7412                // if P == '0' && W == '0' then UNDEFINED;
7413                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7414                  return false;
7415
7416                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7417                t = Bits32 (opcode, 15, 12);
7418                n = Bits32 (opcode, 19, 16);
7419                imm32 = Bits32 (opcode, 7, 0);
7420
7421                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7422                index = BitIsSet (opcode, 10);
7423                add = BitIsSet (opcode, 9);
7424                wback = BitIsSet (opcode, 8);
7425
7426                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7427                if (BadReg (t) || (wback && (n == t)))
7428                    return false;
7429
7430                break;
7431
7432            case eEncodingA1:
7433            {
7434                // if Rn == '1111' then SEE LDRSH (literal);
7435                // if P == '0' && W == '1' then SEE LDRSHT;
7436                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7437                t = Bits32 (opcode, 15, 12);
7438                n = Bits32 (opcode, 19, 16);
7439                uint32_t imm4H = Bits32 (opcode, 11,8);
7440                uint32_t imm4L = Bits32 (opcode, 3, 0);
7441                imm32 = (imm4H << 4) | imm4L;
7442
7443                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7444                index = BitIsSet (opcode, 24);
7445                add = BitIsSet (opcode, 23);
7446                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7447
7448                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7449                if ((t == 15) || (wback && (n == t)))
7450                    return false;
7451
7452                break;
7453            }
7454
7455            default:
7456                return false;
7457        }
7458
7459        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7460        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7461        if (!success)
7462            return false;
7463
7464        addr_t offset_addr;
7465        if (add)
7466            offset_addr = Rn + imm32;
7467        else
7468            offset_addr = Rn - imm32;
7469
7470        // address = if index then offset_addr else R[n];
7471        addr_t address;
7472        if (index)
7473            address = offset_addr;
7474        else
7475            address = Rn;
7476
7477        // data = MemU[address,2];
7478        RegisterInfo base_reg;
7479        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7480
7481        EmulateInstruction::Context context;
7482        context.type = eContextRegisterLoad;
7483        context.SetRegisterPlusOffset (base_reg, address - Rn);
7484
7485        uint64_t data = MemURead (context, address, 2, 0, &success);
7486        if (!success)
7487            return false;
7488
7489        // if wback then R[n] = offset_addr;
7490        if (wback)
7491        {
7492            context.type = eContextAdjustBaseRegister;
7493            context.SetAddress (offset_addr);
7494            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7495                return false;
7496        }
7497
7498        // if UnalignedSupport() || address<0> = '0' then
7499        if (UnalignedSupport() || BitIsClear (address, 0))
7500        {
7501            // R[t] = SignExtend(data, 32);
7502            int64_t signed_data = llvm::SignExtend64<16>(data);
7503            context.type = eContextRegisterLoad;
7504            context.SetRegisterPlusOffset (base_reg, address - Rn);
7505            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7506                return false;
7507        }
7508        else // Can only apply before ARMv7
7509        {
7510            // R[t] = bits(32) UNKNOWN;
7511            WriteBits32Unknown (t);
7512        }
7513    }
7514    return true;
7515}
7516
7517// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7518// sign-extends it to from a 32-bit word, and writes it to a register.
7519bool
7520EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7521{
7522#if 0
7523    if ConditionPassed() then
7524        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7525        base = Align(PC,4);
7526        address = if add then (base + imm32) else (base - imm32);
7527        data = MemU[address,2];
7528        if UnalignedSupport() || address<0> = '0' then
7529            R[t] = SignExtend(data, 32);
7530        else // Can only apply before ARMv7
7531            R[t] = bits(32) UNKNOWN;
7532#endif
7533
7534    bool success = false;
7535
7536    if (ConditionPassed(opcode))
7537    {
7538        uint32_t t;
7539        uint32_t imm32;
7540        bool add;
7541
7542        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7543        switch (encoding)
7544        {
7545            case eEncodingT1:
7546                // if Rt == '1111' then SEE "Unallocated memory hints";
7547                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7548                t = Bits32  (opcode, 15, 12);
7549                imm32 = Bits32 (opcode, 11, 0);
7550                add = BitIsSet (opcode, 23);
7551
7552                // if t == 13 then UNPREDICTABLE;
7553                if (t == 13)
7554                    return false;
7555
7556                break;
7557
7558            case eEncodingA1:
7559            {
7560                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7561                t = Bits32 (opcode, 15, 12);
7562                uint32_t imm4H = Bits32 (opcode, 11, 8);
7563                uint32_t imm4L = Bits32 (opcode, 3, 0);
7564                imm32 = (imm4H << 4) | imm4L;
7565                add = BitIsSet (opcode, 23);
7566
7567                // if t == 15 then UNPREDICTABLE;
7568                if (t == 15)
7569                    return false;
7570
7571                break;
7572            }
7573            default:
7574                return false;
7575        }
7576
7577        // base = Align(PC,4);
7578        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7579        if (!success)
7580            return false;
7581
7582        uint64_t base = AlignPC (pc_value);
7583
7584        addr_t address;
7585        // address = if add then (base + imm32) else (base - imm32);
7586        if (add)
7587            address = base + imm32;
7588        else
7589            address = base - imm32;
7590
7591        // data = MemU[address,2];
7592        RegisterInfo base_reg;
7593        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7594
7595        EmulateInstruction::Context context;
7596        context.type = eContextRegisterLoad;
7597        context.SetRegisterPlusOffset (base_reg, imm32);
7598
7599        uint64_t data = MemURead (context, address, 2, 0, &success);
7600        if (!success)
7601            return false;
7602
7603        // if UnalignedSupport() || address<0> = '0' then
7604        if (UnalignedSupport() || BitIsClear (address, 0))
7605        {
7606            // R[t] = SignExtend(data, 32);
7607            int64_t signed_data = llvm::SignExtend64<16>(data);
7608            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7609                return false;
7610        }
7611        else // Can only apply before ARMv7
7612        {
7613            // R[t] = bits(32) UNKNOWN;
7614            WriteBits32Unknown (t);
7615        }
7616    }
7617    return true;
7618}
7619
7620// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7621// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7622// shifted left by 0, 1, 2, or 3 bits.
7623bool
7624EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7625{
7626#if 0
7627    if ConditionPassed() then
7628        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7629        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7630        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7631        address = if index then offset_addr else R[n];
7632        data = MemU[address,2];
7633        if wback then R[n] = offset_addr;
7634        if UnalignedSupport() || address<0> = '0' then
7635            R[t] = SignExtend(data, 32);
7636        else // Can only apply before ARMv7
7637            R[t] = bits(32) UNKNOWN;
7638#endif
7639
7640    bool success = false;
7641
7642    if (ConditionPassed(opcode))
7643    {
7644        uint32_t t;
7645        uint32_t n;
7646        uint32_t m;
7647        bool index;
7648        bool add;
7649        bool wback;
7650        ARM_ShifterType shift_t;
7651        uint32_t shift_n;
7652
7653        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7654        switch (encoding)
7655        {
7656            case eEncodingT1:
7657                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7658                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7659                t = Bits32 (opcode, 2, 0);
7660                n = Bits32 (opcode, 5, 3);
7661                m = Bits32 (opcode, 8, 6);
7662
7663                // index = TRUE; add = TRUE; wback = FALSE;
7664                index = true;
7665                add = true;
7666                wback = false;
7667
7668                // (shift_t, shift_n) = (SRType_LSL, 0);
7669                shift_t = SRType_LSL;
7670                shift_n = 0;
7671
7672                break;
7673
7674            case eEncodingT2:
7675                // if Rn == '1111' then SEE LDRSH (literal);
7676                // if Rt == '1111' then SEE "Unallocated memory hints";
7677                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7678                t = Bits32 (opcode, 15, 12);
7679                n = Bits32 (opcode, 19, 16);
7680                m = Bits32 (opcode, 3, 0);
7681
7682                // index = TRUE; add = TRUE; wback = FALSE;
7683                index = true;
7684                add = true;
7685                wback = false;
7686
7687                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7688                shift_t = SRType_LSL;
7689                shift_n = Bits32 (opcode, 5, 4);
7690
7691                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7692                if ((t == 13) || BadReg (m))
7693                    return false;
7694
7695                break;
7696
7697            case eEncodingA1:
7698                // if P == '0' && W == '1' then SEE LDRSHT;
7699                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7700                t = Bits32 (opcode, 15, 12);
7701                n = Bits32 (opcode, 19, 16);
7702                m = Bits32 (opcode, 3, 0);
7703
7704                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7705                index = BitIsSet (opcode, 24);
7706                add = BitIsSet (opcode, 23);
7707                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7708
7709                // (shift_t, shift_n) = (SRType_LSL, 0);
7710                shift_t = SRType_LSL;
7711                shift_n = 0;
7712
7713                // if t == 15 || m == 15 then UNPREDICTABLE;
7714                if ((t == 15) || (m == 15))
7715                    return false;
7716
7717                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7718                if (wback && ((n == 15) || (n == t)))
7719                    return false;
7720
7721                break;
7722
7723            default:
7724                return false;
7725        }
7726
7727        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7728        if (!success)
7729            return false;
7730
7731        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7732        if (!success)
7733            return false;
7734
7735        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7736        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7737        if (!success)
7738            return false;
7739
7740        addr_t offset_addr;
7741        addr_t address;
7742
7743        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7744        if (add)
7745            offset_addr = Rn + offset;
7746        else
7747            offset_addr = Rn - offset;
7748
7749        // address = if index then offset_addr else R[n];
7750        if (index)
7751            address = offset_addr;
7752        else
7753            address = Rn;
7754
7755        // data = MemU[address,2];
7756        RegisterInfo base_reg;
7757        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7758
7759        RegisterInfo offset_reg;
7760        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7761
7762        EmulateInstruction::Context context;
7763        context.type = eContextRegisterLoad;
7764        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7765
7766        uint64_t data = MemURead (context, address, 2, 0, &success);
7767        if (!success)
7768            return false;
7769
7770        // if wback then R[n] = offset_addr;
7771        if (wback)
7772        {
7773            context.type = eContextAdjustBaseRegister;
7774            context.SetAddress (offset_addr);
7775            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7776                return false;
7777        }
7778
7779        // if UnalignedSupport() || address<0> = '0' then
7780        if (UnalignedSupport() || BitIsClear (address, 0))
7781        {
7782            // R[t] = SignExtend(data, 32);
7783            context.type = eContextRegisterLoad;
7784            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7785
7786            int64_t signed_data = llvm::SignExtend64<16>(data);
7787            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7788                return false;
7789        }
7790        else // Can only apply before ARMv7
7791        {
7792            // R[t] = bits(32) UNKNOWN;
7793            WriteBits32Unknown (t);
7794        }
7795    }
7796    return true;
7797}
7798
7799// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7800// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7801bool
7802EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7803{
7804#if 0
7805    if ConditionPassed() then
7806        EncodingSpecificOperations();
7807        rotated = ROR(R[m], rotation);
7808        R[d] = SignExtend(rotated<7:0>, 32);
7809#endif
7810
7811    bool success = false;
7812
7813    if (ConditionPassed(opcode))
7814    {
7815        uint32_t d;
7816        uint32_t m;
7817        uint32_t rotation;
7818
7819        // EncodingSpecificOperations();
7820        switch (encoding)
7821        {
7822            case eEncodingT1:
7823                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7824                d = Bits32 (opcode, 2, 0);
7825                m = Bits32 (opcode, 5, 3);
7826                rotation = 0;
7827
7828                break;
7829
7830            case eEncodingT2:
7831                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7832                d = Bits32 (opcode, 11, 8);
7833                m = Bits32 (opcode, 3, 0);
7834                rotation = Bits32 (opcode, 5, 4) << 3;
7835
7836                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7837                if (BadReg (d) || BadReg (m))
7838                    return false;
7839
7840                break;
7841
7842            case eEncodingA1:
7843                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7844                d = Bits32 (opcode, 15, 12);
7845                m = Bits32 (opcode, 3, 0);
7846                rotation = Bits32 (opcode, 11, 10) << 3;
7847
7848                // if d == 15 || m == 15 then UNPREDICTABLE;
7849                if ((d == 15) || (m == 15))
7850                    return false;
7851
7852                break;
7853
7854            default:
7855                return false;
7856        }
7857
7858        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7859        if (!success)
7860            return false;
7861
7862        // rotated = ROR(R[m], rotation);
7863        uint64_t rotated = ROR (Rm, rotation, &success);
7864        if (!success)
7865            return false;
7866
7867        // R[d] = SignExtend(rotated<7:0>, 32);
7868        int64_t data = llvm::SignExtend64<8>(rotated);
7869
7870        RegisterInfo source_reg;
7871        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7872
7873        EmulateInstruction::Context context;
7874        context.type = eContextRegisterLoad;
7875        context.SetRegister (source_reg);
7876
7877        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7878            return false;
7879    }
7880    return true;
7881}
7882
7883// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7884// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7885bool
7886EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7887{
7888#if 0
7889    if ConditionPassed() then
7890        EncodingSpecificOperations();
7891        rotated = ROR(R[m], rotation);
7892        R[d] = SignExtend(rotated<15:0>, 32);
7893#endif
7894
7895    bool success = false;
7896
7897    if (ConditionPassed(opcode))
7898    {
7899        uint32_t d;
7900        uint32_t m;
7901        uint32_t rotation;
7902
7903        // EncodingSpecificOperations();
7904        switch (encoding)
7905        {
7906            case eEncodingT1:
7907                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7908                d = Bits32 (opcode, 2, 0);
7909                m = Bits32 (opcode, 5, 3);
7910                rotation = 0;
7911
7912                break;
7913
7914            case eEncodingT2:
7915                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7916                d = Bits32 (opcode, 11, 8);
7917                m = Bits32 (opcode, 3, 0);
7918                rotation = Bits32 (opcode, 5, 4) << 3;
7919
7920                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7921                if (BadReg (d) || BadReg (m))
7922                    return false;
7923
7924                break;
7925
7926            case eEncodingA1:
7927                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7928                d = Bits32 (opcode, 15, 12);
7929                m = Bits32 (opcode, 3, 0);
7930                rotation = Bits32 (opcode, 11, 10) << 3;
7931
7932                // if d == 15 || m == 15 then UNPREDICTABLE;
7933                if ((d == 15) || (m == 15))
7934                    return false;
7935
7936                break;
7937
7938            default:
7939                return false;
7940        }
7941
7942        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7943        if (!success)
7944            return false;
7945
7946        // rotated = ROR(R[m], rotation);
7947        uint64_t rotated = ROR (Rm, rotation, &success);
7948        if (!success)
7949            return false;
7950
7951        // R[d] = SignExtend(rotated<15:0>, 32);
7952        RegisterInfo source_reg;
7953        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7954
7955        EmulateInstruction::Context context;
7956        context.type = eContextRegisterLoad;
7957        context.SetRegister (source_reg);
7958
7959        int64_t data = llvm::SignExtend64<16> (rotated);
7960        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7961            return false;
7962    }
7963
7964    return true;
7965}
7966
7967// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7968// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7969bool
7970EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7971{
7972#if 0
7973    if ConditionPassed() then
7974        EncodingSpecificOperations();
7975        rotated = ROR(R[m], rotation);
7976        R[d] = ZeroExtend(rotated<7:0>, 32);
7977#endif
7978
7979    bool success = false;
7980
7981    if (ConditionPassed(opcode))
7982    {
7983        uint32_t d;
7984        uint32_t m;
7985        uint32_t rotation;
7986
7987        // EncodingSpecificOperations();
7988        switch (encoding)
7989        {
7990            case eEncodingT1:
7991                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7992                d = Bits32 (opcode, 2, 0);
7993                m = Bits32 (opcode, 5, 3);
7994                rotation = 0;
7995
7996                break;
7997
7998            case eEncodingT2:
7999                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8000                d = Bits32 (opcode, 11, 8);
8001                m = Bits32 (opcode, 3, 0);
8002                  rotation = Bits32 (opcode, 5, 4) << 3;
8003
8004                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8005                if (BadReg (d) || BadReg (m))
8006                  return false;
8007
8008                break;
8009
8010            case eEncodingA1:
8011                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8012                d = Bits32 (opcode, 15, 12);
8013                m = Bits32 (opcode, 3, 0);
8014                rotation = Bits32 (opcode, 11, 10) << 3;
8015
8016                // if d == 15 || m == 15 then UNPREDICTABLE;
8017                if ((d == 15) || (m == 15))
8018                    return false;
8019
8020                break;
8021
8022            default:
8023                return false;
8024        }
8025
8026        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8027        if (!success)
8028            return false;
8029
8030        // rotated = ROR(R[m], rotation);
8031        uint64_t rotated = ROR (Rm, rotation, &success);
8032        if (!success)
8033            return false;
8034
8035        // R[d] = ZeroExtend(rotated<7:0>, 32);
8036        RegisterInfo source_reg;
8037        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8038
8039        EmulateInstruction::Context context;
8040        context.type = eContextRegisterLoad;
8041        context.SetRegister (source_reg);
8042
8043        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8044            return false;
8045    }
8046    return true;
8047}
8048
8049// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8050// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8051bool
8052EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8053{
8054#if 0
8055    if ConditionPassed() then
8056        EncodingSpecificOperations();
8057        rotated = ROR(R[m], rotation);
8058        R[d] = ZeroExtend(rotated<15:0>, 32);
8059#endif
8060
8061    bool success = false;
8062
8063    if (ConditionPassed(opcode))
8064    {
8065        uint32_t d;
8066        uint32_t m;
8067        uint32_t rotation;
8068
8069        switch (encoding)
8070        {
8071            case eEncodingT1:
8072                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8073                d = Bits32 (opcode, 2, 0);
8074                m = Bits32 (opcode, 5, 3);
8075                rotation = 0;
8076
8077                break;
8078
8079            case eEncodingT2:
8080                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8081                d = Bits32 (opcode, 11, 8);
8082                m = Bits32 (opcode, 3, 0);
8083                rotation = Bits32 (opcode, 5, 4) << 3;
8084
8085                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8086                if (BadReg (d) || BadReg (m))
8087                  return false;
8088
8089                break;
8090
8091            case eEncodingA1:
8092                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8093                d = Bits32 (opcode, 15, 12);
8094                m = Bits32 (opcode, 3, 0);
8095                rotation = Bits32 (opcode, 11, 10) << 3;
8096
8097                // if d == 15 || m == 15 then UNPREDICTABLE;
8098                if ((d == 15) || (m == 15))
8099                    return false;
8100
8101                break;
8102
8103            default:
8104                return false;
8105        }
8106
8107        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8108        if (!success)
8109            return false;
8110
8111        // rotated = ROR(R[m], rotation);
8112        uint64_t rotated = ROR (Rm, rotation, &success);
8113        if (!success)
8114            return false;
8115
8116        // R[d] = ZeroExtend(rotated<15:0>, 32);
8117        RegisterInfo source_reg;
8118        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8119
8120        EmulateInstruction::Context context;
8121        context.type = eContextRegisterLoad;
8122        context.SetRegister (source_reg);
8123
8124        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8125            return false;
8126    }
8127    return true;
8128}
8129
8130// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8131// word respectively.
8132bool
8133EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8134{
8135#if 0
8136    if ConditionPassed() then
8137        EncodingSpecificOperations();
8138        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8139            UNPREDICTABLE;
8140        else
8141            address = if increment then R[n] else R[n]-8;
8142            if wordhigher then address = address+4;
8143            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8144            BranchWritePC(MemA[address,4]);
8145            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8146#endif
8147
8148    bool success = false;
8149
8150    if (ConditionPassed(opcode))
8151    {
8152        uint32_t n;
8153        bool wback;
8154        bool increment;
8155        bool wordhigher;
8156
8157        // EncodingSpecificOperations();
8158        switch (encoding)
8159        {
8160            case eEncodingT1:
8161                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8162                n = Bits32 (opcode, 19, 16);
8163                wback = BitIsSet (opcode, 21);
8164                increment = false;
8165                wordhigher = false;
8166
8167                // if n == 15 then UNPREDICTABLE;
8168                if (n == 15)
8169                    return false;
8170
8171                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8172                if (InITBlock() && !LastInITBlock())
8173                    return false;
8174
8175                break;
8176
8177            case eEncodingT2:
8178                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8179                n = Bits32 (opcode, 19, 16);
8180                wback = BitIsSet (opcode, 21);
8181                increment = true;
8182                wordhigher = false;
8183
8184                // if n == 15 then UNPREDICTABLE;
8185                if (n == 15)
8186                    return false;
8187
8188                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8189                if (InITBlock() && !LastInITBlock())
8190                    return false;
8191
8192                break;
8193
8194            case eEncodingA1:
8195                // n = UInt(Rn);
8196                n = Bits32 (opcode, 19, 16);
8197
8198                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8199                wback = BitIsSet (opcode, 21);
8200                increment = BitIsSet (opcode, 23);
8201                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8202
8203                // if n == 15 then UNPREDICTABLE;
8204                if (n == 15)
8205                    return false;
8206
8207                break;
8208
8209            default:
8210                return false;
8211        }
8212
8213        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8214        if (!CurrentModeIsPrivileged ())
8215            // UNPREDICTABLE;
8216            return false;
8217        else
8218        {
8219            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8220            if (!success)
8221                return false;
8222
8223            addr_t address;
8224            // address = if increment then R[n] else R[n]-8;
8225            if (increment)
8226                address = Rn;
8227            else
8228                address = Rn - 8;
8229
8230            // if wordhigher then address = address+4;
8231            if (wordhigher)
8232                address = address + 4;
8233
8234            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8235            RegisterInfo base_reg;
8236            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8237
8238            EmulateInstruction::Context context;
8239            context.type = eContextReturnFromException;
8240            context.SetRegisterPlusOffset (base_reg, address - Rn);
8241
8242            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8243            if (!success)
8244                return false;
8245
8246            CPSRWriteByInstr (data, 15, true);
8247
8248            // BranchWritePC(MemA[address,4]);
8249            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8250            if (!success)
8251                return false;
8252
8253            BranchWritePC (context, data2);
8254
8255            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8256            if (wback)
8257            {
8258                context.type = eContextAdjustBaseRegister;
8259                if (increment)
8260                {
8261                    context.SetOffset (8);
8262                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8263                        return false;
8264                }
8265                else
8266                {
8267                    context.SetOffset (-8);
8268                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8269                        return false;
8270                }
8271            } // if wback
8272        }
8273    } // if ConditionPassed()
8274    return true;
8275}
8276
8277// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8278// and writes the result to the destination register.  It can optionally update the condition flags based on
8279// the result.
8280bool
8281EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8282{
8283#if 0
8284    // ARM pseudo code...
8285    if ConditionPassed() then
8286        EncodingSpecificOperations();
8287        result = R[n] EOR imm32;
8288        if d == 15 then         // Can only occur for ARM encoding
8289            ALUWritePC(result); // setflags is always FALSE here
8290        else
8291            R[d] = result;
8292            if setflags then
8293                APSR.N = result<31>;
8294                APSR.Z = IsZeroBit(result);
8295                APSR.C = carry;
8296                // APSR.V unchanged
8297#endif
8298
8299    bool success = false;
8300
8301    if (ConditionPassed(opcode))
8302    {
8303        uint32_t Rd, Rn;
8304        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8305        bool setflags;
8306        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8307        switch (encoding)
8308        {
8309        case eEncodingT1:
8310            Rd = Bits32(opcode, 11, 8);
8311            Rn = Bits32(opcode, 19, 16);
8312            setflags = BitIsSet(opcode, 20);
8313            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8314            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8315            if (Rd == 15 && setflags)
8316                return EmulateTEQImm (opcode, eEncodingT1);
8317            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8318                return false;
8319            break;
8320        case eEncodingA1:
8321            Rd = Bits32(opcode, 15, 12);
8322            Rn = Bits32(opcode, 19, 16);
8323            setflags = BitIsSet(opcode, 20);
8324            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8325
8326            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8327            if (Rd == 15 && setflags)
8328                return EmulateSUBSPcLrEtc (opcode, encoding);
8329            break;
8330        default:
8331            return false;
8332        }
8333
8334        // Read the first operand.
8335        uint32_t val1 = ReadCoreReg(Rn, &success);
8336        if (!success)
8337            return false;
8338
8339        uint32_t result = val1 ^ imm32;
8340
8341        EmulateInstruction::Context context;
8342        context.type = EmulateInstruction::eContextImmediate;
8343        context.SetNoArgs ();
8344
8345        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8346            return false;
8347    }
8348    return true;
8349}
8350
8351// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8352// optionally-shifted register value, and writes the result to the destination register.
8353// It can optionally update the condition flags based on the result.
8354bool
8355EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8356{
8357#if 0
8358    // ARM pseudo code...
8359    if ConditionPassed() then
8360        EncodingSpecificOperations();
8361        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8362        result = R[n] EOR shifted;
8363        if d == 15 then         // Can only occur for ARM encoding
8364            ALUWritePC(result); // setflags is always FALSE here
8365        else
8366            R[d] = result;
8367            if setflags then
8368                APSR.N = result<31>;
8369                APSR.Z = IsZeroBit(result);
8370                APSR.C = carry;
8371                // APSR.V unchanged
8372#endif
8373
8374    bool success = false;
8375
8376    if (ConditionPassed(opcode))
8377    {
8378        uint32_t Rd, Rn, Rm;
8379        ARM_ShifterType shift_t;
8380        uint32_t shift_n; // the shift applied to the value read from Rm
8381        bool setflags;
8382        uint32_t carry;
8383        switch (encoding)
8384        {
8385        case eEncodingT1:
8386            Rd = Rn = Bits32(opcode, 2, 0);
8387            Rm = Bits32(opcode, 5, 3);
8388            setflags = !InITBlock();
8389            shift_t = SRType_LSL;
8390            shift_n = 0;
8391            break;
8392        case eEncodingT2:
8393            Rd = Bits32(opcode, 11, 8);
8394            Rn = Bits32(opcode, 19, 16);
8395            Rm = Bits32(opcode, 3, 0);
8396            setflags = BitIsSet(opcode, 20);
8397            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8398            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8399            if (Rd == 15 && setflags)
8400                return EmulateTEQReg (opcode, eEncodingT1);
8401            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8402                return false;
8403            break;
8404        case eEncodingA1:
8405            Rd = Bits32(opcode, 15, 12);
8406            Rn = Bits32(opcode, 19, 16);
8407            Rm = Bits32(opcode, 3, 0);
8408            setflags = BitIsSet(opcode, 20);
8409            shift_n = DecodeImmShiftARM(opcode, shift_t);
8410
8411            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8412            if (Rd == 15 && setflags)
8413                return EmulateSUBSPcLrEtc (opcode, encoding);
8414            break;
8415        default:
8416            return false;
8417        }
8418
8419        // Read the first operand.
8420        uint32_t val1 = ReadCoreReg(Rn, &success);
8421        if (!success)
8422            return false;
8423
8424        // Read the second operand.
8425        uint32_t val2 = ReadCoreReg(Rm, &success);
8426        if (!success)
8427            return false;
8428
8429        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8430        if (!success)
8431            return false;
8432        uint32_t result = val1 ^ shifted;
8433
8434        EmulateInstruction::Context context;
8435        context.type = EmulateInstruction::eContextImmediate;
8436        context.SetNoArgs ();
8437
8438        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8439            return false;
8440    }
8441    return true;
8442}
8443
8444// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8445// writes the result to the destination register.  It can optionally update the condition flags based
8446// on the result.
8447bool
8448EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8449{
8450#if 0
8451    // ARM pseudo code...
8452    if ConditionPassed() then
8453        EncodingSpecificOperations();
8454        result = R[n] OR imm32;
8455        if d == 15 then         // Can only occur for ARM encoding
8456            ALUWritePC(result); // setflags is always FALSE here
8457        else
8458            R[d] = result;
8459            if setflags then
8460                APSR.N = result<31>;
8461                APSR.Z = IsZeroBit(result);
8462                APSR.C = carry;
8463                // APSR.V unchanged
8464#endif
8465
8466    bool success = false;
8467
8468    if (ConditionPassed(opcode))
8469    {
8470        uint32_t Rd, Rn;
8471        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8472        bool setflags;
8473        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8474        switch (encoding)
8475        {
8476        case eEncodingT1:
8477            Rd = Bits32(opcode, 11, 8);
8478            Rn = Bits32(opcode, 19, 16);
8479            setflags = BitIsSet(opcode, 20);
8480            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8481            // if Rn == '1111' then SEE MOV (immediate);
8482            if (Rn == 15)
8483                return EmulateMOVRdImm (opcode, eEncodingT2);
8484            if (BadReg(Rd) || Rn == 13)
8485                return false;
8486            break;
8487        case eEncodingA1:
8488            Rd = Bits32(opcode, 15, 12);
8489            Rn = Bits32(opcode, 19, 16);
8490            setflags = BitIsSet(opcode, 20);
8491            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8492
8493            if (Rd == 15 && setflags)
8494                return EmulateSUBSPcLrEtc (opcode, encoding);
8495            break;
8496        default:
8497            return false;
8498        }
8499
8500        // Read the first operand.
8501        uint32_t val1 = ReadCoreReg(Rn, &success);
8502        if (!success)
8503            return false;
8504
8505        uint32_t result = val1 | imm32;
8506
8507        EmulateInstruction::Context context;
8508        context.type = EmulateInstruction::eContextImmediate;
8509        context.SetNoArgs ();
8510
8511        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8512            return false;
8513    }
8514    return true;
8515}
8516
8517// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8518// value, and writes the result to the destination register.  It can optionally update the condition flags based
8519// on the result.
8520bool
8521EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8522{
8523#if 0
8524    // ARM pseudo code...
8525    if ConditionPassed() then
8526        EncodingSpecificOperations();
8527        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8528        result = R[n] OR shifted;
8529        if d == 15 then         // Can only occur for ARM encoding
8530            ALUWritePC(result); // setflags is always FALSE here
8531        else
8532            R[d] = result;
8533            if setflags then
8534                APSR.N = result<31>;
8535                APSR.Z = IsZeroBit(result);
8536                APSR.C = carry;
8537                // APSR.V unchanged
8538#endif
8539
8540    bool success = false;
8541
8542    if (ConditionPassed(opcode))
8543    {
8544        uint32_t Rd, Rn, Rm;
8545        ARM_ShifterType shift_t;
8546        uint32_t shift_n; // the shift applied to the value read from Rm
8547        bool setflags;
8548        uint32_t carry;
8549        switch (encoding)
8550        {
8551        case eEncodingT1:
8552            Rd = Rn = Bits32(opcode, 2, 0);
8553            Rm = Bits32(opcode, 5, 3);
8554            setflags = !InITBlock();
8555            shift_t = SRType_LSL;
8556            shift_n = 0;
8557            break;
8558        case eEncodingT2:
8559            Rd = Bits32(opcode, 11, 8);
8560            Rn = Bits32(opcode, 19, 16);
8561            Rm = Bits32(opcode, 3, 0);
8562            setflags = BitIsSet(opcode, 20);
8563            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8564            // if Rn == '1111' then SEE MOV (register);
8565            if (Rn == 15)
8566                return EmulateMOVRdRm (opcode, eEncodingT3);
8567            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8568                return false;
8569            break;
8570        case eEncodingA1:
8571            Rd = Bits32(opcode, 15, 12);
8572            Rn = Bits32(opcode, 19, 16);
8573            Rm = Bits32(opcode, 3, 0);
8574            setflags = BitIsSet(opcode, 20);
8575            shift_n = DecodeImmShiftARM(opcode, shift_t);
8576
8577            if (Rd == 15 && setflags)
8578                return EmulateSUBSPcLrEtc (opcode, encoding);
8579            break;
8580        default:
8581            return false;
8582        }
8583
8584        // Read the first operand.
8585        uint32_t val1 = ReadCoreReg(Rn, &success);
8586        if (!success)
8587            return false;
8588
8589        // Read the second operand.
8590        uint32_t val2 = ReadCoreReg(Rm, &success);
8591        if (!success)
8592            return false;
8593
8594        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8595        if (!success)
8596            return false;
8597        uint32_t result = val1 | shifted;
8598
8599        EmulateInstruction::Context context;
8600        context.type = EmulateInstruction::eContextImmediate;
8601        context.SetNoArgs ();
8602
8603        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8604            return false;
8605    }
8606    return true;
8607}
8608
8609// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8610// the destination register. It can optionally update the condition flags based on the result.
8611bool
8612EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8613{
8614#if 0
8615    // ARM pseudo code...
8616    if ConditionPassed() then
8617        EncodingSpecificOperations();
8618        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8619        if d == 15 then         // Can only occur for ARM encoding
8620            ALUWritePC(result); // setflags is always FALSE here
8621        else
8622            R[d] = result;
8623            if setflags then
8624                APSR.N = result<31>;
8625                APSR.Z = IsZeroBit(result);
8626                APSR.C = carry;
8627                APSR.V = overflow;
8628#endif
8629
8630    bool success = false;
8631
8632    uint32_t Rd; // the destination register
8633    uint32_t Rn; // the first operand
8634    bool setflags;
8635    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8636    switch (encoding) {
8637    case eEncodingT1:
8638        Rd = Bits32(opcode, 2, 0);
8639        Rn = Bits32(opcode, 5, 3);
8640        setflags = !InITBlock();
8641        imm32 = 0;
8642        break;
8643    case eEncodingT2:
8644        Rd = Bits32(opcode, 11, 8);
8645        Rn = Bits32(opcode, 19, 16);
8646        setflags = BitIsSet(opcode, 20);
8647        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8648        if (BadReg(Rd) || BadReg(Rn))
8649            return false;
8650        break;
8651    case eEncodingA1:
8652        Rd = Bits32(opcode, 15, 12);
8653        Rn = Bits32(opcode, 19, 16);
8654        setflags = BitIsSet(opcode, 20);
8655        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8656
8657        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8658        if (Rd == 15 && setflags)
8659            return EmulateSUBSPcLrEtc (opcode, encoding);
8660        break;
8661    default:
8662        return false;
8663    }
8664    // Read the register value from the operand register Rn.
8665    uint32_t reg_val = ReadCoreReg(Rn, &success);
8666    if (!success)
8667        return false;
8668
8669    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8670
8671    EmulateInstruction::Context context;
8672    context.type = EmulateInstruction::eContextImmediate;
8673    context.SetNoArgs ();
8674
8675    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8676        return false;
8677
8678    return true;
8679}
8680
8681// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8682// result to the destination register. It can optionally update the condition flags based on the result.
8683bool
8684EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8685{
8686#if 0
8687    // ARM pseudo code...
8688    if ConditionPassed() then
8689        EncodingSpecificOperations();
8690        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8691        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8692        if d == 15 then         // Can only occur for ARM encoding
8693            ALUWritePC(result); // setflags is always FALSE here
8694        else
8695            R[d] = result;
8696            if setflags then
8697                APSR.N = result<31>;
8698                APSR.Z = IsZeroBit(result);
8699                APSR.C = carry;
8700                APSR.V = overflow;
8701#endif
8702
8703    bool success = false;
8704
8705    uint32_t Rd; // the destination register
8706    uint32_t Rn; // the first operand
8707    uint32_t Rm; // the second operand
8708    bool setflags;
8709    ARM_ShifterType shift_t;
8710    uint32_t shift_n; // the shift applied to the value read from Rm
8711    switch (encoding) {
8712    case eEncodingT1:
8713        Rd = Bits32(opcode, 11, 8);
8714        Rn = Bits32(opcode, 19, 16);
8715        Rm = Bits32(opcode, 3, 0);
8716        setflags = BitIsSet(opcode, 20);
8717        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8718        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8719        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8720            return false;
8721        break;
8722    case eEncodingA1:
8723        Rd = Bits32(opcode, 15, 12);
8724        Rn = Bits32(opcode, 19, 16);
8725        Rm = Bits32(opcode, 3, 0);
8726        setflags = BitIsSet(opcode, 20);
8727        shift_n = DecodeImmShiftARM(opcode, shift_t);
8728
8729        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8730        if (Rd == 15 && setflags)
8731            return EmulateSUBSPcLrEtc (opcode, encoding);
8732        break;
8733    default:
8734        return false;
8735    }
8736    // Read the register value from register Rn.
8737    uint32_t val1 = ReadCoreReg(Rn, &success);
8738    if (!success)
8739        return false;
8740
8741    // Read the register value from register Rm.
8742    uint32_t val2 = ReadCoreReg(Rm, &success);
8743    if (!success)
8744        return false;
8745
8746    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8747    if (!success)
8748        return false;
8749    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8750
8751    EmulateInstruction::Context context;
8752    context.type = EmulateInstruction::eContextImmediate;
8753    context.SetNoArgs();
8754    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8755        return false;
8756
8757    return true;
8758}
8759
8760// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8761// an immediate value, and writes the result to the destination register. It can optionally update the condition
8762// flags based on the result.
8763bool
8764EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8765{
8766#if 0
8767    // ARM pseudo code...
8768    if ConditionPassed() then
8769        EncodingSpecificOperations();
8770        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8771        if d == 15 then
8772            ALUWritePC(result); // setflags is always FALSE here
8773        else
8774            R[d] = result;
8775            if setflags then
8776                APSR.N = result<31>;
8777                APSR.Z = IsZeroBit(result);
8778                APSR.C = carry;
8779                APSR.V = overflow;
8780#endif
8781
8782    bool success = false;
8783
8784    uint32_t Rd; // the destination register
8785    uint32_t Rn; // the first operand
8786    bool setflags;
8787    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8788    switch (encoding) {
8789    case eEncodingA1:
8790        Rd = Bits32(opcode, 15, 12);
8791        Rn = Bits32(opcode, 19, 16);
8792        setflags = BitIsSet(opcode, 20);
8793        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8794
8795        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8796        if (Rd == 15 && setflags)
8797            return EmulateSUBSPcLrEtc  (opcode, encoding);
8798        break;
8799    default:
8800        return false;
8801    }
8802    // Read the register value from the operand register Rn.
8803    uint32_t reg_val = ReadCoreReg(Rn, &success);
8804    if (!success)
8805        return false;
8806
8807    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8808
8809    EmulateInstruction::Context context;
8810    context.type = EmulateInstruction::eContextImmediate;
8811    context.SetNoArgs ();
8812
8813    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8814        return false;
8815
8816    return true;
8817}
8818
8819// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8820// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8821// condition flags based on the result.
8822bool
8823EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8824{
8825#if 0
8826    // ARM pseudo code...
8827    if ConditionPassed() then
8828        EncodingSpecificOperations();
8829        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8830        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8831        if d == 15 then
8832            ALUWritePC(result); // setflags is always FALSE here
8833        else
8834            R[d] = result;
8835            if setflags then
8836                APSR.N = result<31>;
8837                APSR.Z = IsZeroBit(result);
8838                APSR.C = carry;
8839                APSR.V = overflow;
8840#endif
8841
8842    bool success = false;
8843
8844    uint32_t Rd; // the destination register
8845    uint32_t Rn; // the first operand
8846    uint32_t Rm; // the second operand
8847    bool setflags;
8848    ARM_ShifterType shift_t;
8849    uint32_t shift_n; // the shift applied to the value read from Rm
8850    switch (encoding) {
8851    case eEncodingA1:
8852        Rd = Bits32(opcode, 15, 12);
8853        Rn = Bits32(opcode, 19, 16);
8854        Rm = Bits32(opcode, 3, 0);
8855        setflags = BitIsSet(opcode, 20);
8856        shift_n = DecodeImmShiftARM(opcode, shift_t);
8857
8858        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8859        if (Rd == 15 && setflags)
8860            return EmulateSUBSPcLrEtc (opcode, encoding);
8861        break;
8862    default:
8863        return false;
8864    }
8865    // Read the register value from register Rn.
8866    uint32_t val1 = ReadCoreReg(Rn, &success);
8867    if (!success)
8868        return false;
8869
8870    // Read the register value from register Rm.
8871    uint32_t val2 = ReadCoreReg(Rm, &success);
8872    if (!success)
8873        return false;
8874
8875    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8876    if (!success)
8877        return false;
8878    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8879
8880    EmulateInstruction::Context context;
8881    context.type = EmulateInstruction::eContextImmediate;
8882    context.SetNoArgs();
8883    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8884        return false;
8885
8886    return true;
8887}
8888
8889// Subtract with Carry (immediate) subtracts an immediate value and the value of
8890// NOT (Carry flag) from a register value, and writes the result to the destination register.
8891// It can optionally update the condition flags based on the result.
8892bool
8893EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8894{
8895#if 0
8896    // ARM pseudo code...
8897    if ConditionPassed() then
8898        EncodingSpecificOperations();
8899        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8900        if d == 15 then         // Can only occur for ARM encoding
8901            ALUWritePC(result); // setflags is always FALSE here
8902        else
8903            R[d] = result;
8904            if setflags then
8905                APSR.N = result<31>;
8906                APSR.Z = IsZeroBit(result);
8907                APSR.C = carry;
8908                APSR.V = overflow;
8909#endif
8910
8911    bool success = false;
8912
8913    uint32_t Rd; // the destination register
8914    uint32_t Rn; // the first operand
8915    bool setflags;
8916    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8917    switch (encoding) {
8918    case eEncodingT1:
8919        Rd = Bits32(opcode, 11, 8);
8920        Rn = Bits32(opcode, 19, 16);
8921        setflags = BitIsSet(opcode, 20);
8922        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8923        if (BadReg(Rd) || BadReg(Rn))
8924            return false;
8925        break;
8926    case eEncodingA1:
8927        Rd = Bits32(opcode, 15, 12);
8928        Rn = Bits32(opcode, 19, 16);
8929        setflags = BitIsSet(opcode, 20);
8930        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8931
8932        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8933        if (Rd == 15 && setflags)
8934            return EmulateSUBSPcLrEtc (opcode, encoding);
8935        break;
8936    default:
8937        return false;
8938    }
8939    // Read the register value from the operand register Rn.
8940    uint32_t reg_val = ReadCoreReg(Rn, &success);
8941    if (!success)
8942        return false;
8943
8944    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8945
8946    EmulateInstruction::Context context;
8947    context.type = EmulateInstruction::eContextImmediate;
8948    context.SetNoArgs ();
8949
8950    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8951        return false;
8952
8953    return true;
8954}
8955
8956// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8957// NOT (Carry flag) from a register value, and writes the result to the destination register.
8958// It can optionally update the condition flags based on the result.
8959bool
8960EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8961{
8962#if 0
8963    // ARM pseudo code...
8964    if ConditionPassed() then
8965        EncodingSpecificOperations();
8966        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8967        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8968        if d == 15 then         // Can only occur for ARM encoding
8969            ALUWritePC(result); // setflags is always FALSE here
8970        else
8971            R[d] = result;
8972            if setflags then
8973                APSR.N = result<31>;
8974                APSR.Z = IsZeroBit(result);
8975                APSR.C = carry;
8976                APSR.V = overflow;
8977#endif
8978
8979    bool success = false;
8980
8981    uint32_t Rd; // the destination register
8982    uint32_t Rn; // the first operand
8983    uint32_t Rm; // the second operand
8984    bool setflags;
8985    ARM_ShifterType shift_t;
8986    uint32_t shift_n; // the shift applied to the value read from Rm
8987    switch (encoding) {
8988    case eEncodingT1:
8989        Rd = Rn = Bits32(opcode, 2, 0);
8990        Rm = Bits32(opcode, 5, 3);
8991        setflags = !InITBlock();
8992        shift_t = SRType_LSL;
8993        shift_n = 0;
8994        break;
8995    case eEncodingT2:
8996        Rd = Bits32(opcode, 11, 8);
8997        Rn = Bits32(opcode, 19, 16);
8998        Rm = Bits32(opcode, 3, 0);
8999        setflags = BitIsSet(opcode, 20);
9000        shift_n = DecodeImmShiftThumb(opcode, shift_t);
9001        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9002            return false;
9003        break;
9004    case eEncodingA1:
9005        Rd = Bits32(opcode, 15, 12);
9006        Rn = Bits32(opcode, 19, 16);
9007        Rm = Bits32(opcode, 3, 0);
9008        setflags = BitIsSet(opcode, 20);
9009        shift_n = DecodeImmShiftARM(opcode, shift_t);
9010
9011        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9012        if (Rd == 15 && setflags)
9013            return EmulateSUBSPcLrEtc (opcode, encoding);
9014        break;
9015    default:
9016        return false;
9017    }
9018    // Read the register value from register Rn.
9019    uint32_t val1 = ReadCoreReg(Rn, &success);
9020    if (!success)
9021        return false;
9022
9023    // Read the register value from register Rm.
9024    uint32_t val2 = ReadCoreReg(Rm, &success);
9025    if (!success)
9026        return false;
9027
9028    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9029    if (!success)
9030        return false;
9031    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9032
9033    EmulateInstruction::Context context;
9034    context.type = EmulateInstruction::eContextImmediate;
9035    context.SetNoArgs();
9036    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9037        return false;
9038
9039    return true;
9040}
9041
9042// This instruction subtracts an immediate value from a register value, and writes the result
9043// to the destination register.  It can optionally update the condition flags based on the result.
9044bool
9045EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9046{
9047#if 0
9048    // ARM pseudo code...
9049    if ConditionPassed() then
9050        EncodingSpecificOperations();
9051        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9052        R[d] = result;
9053        if setflags then
9054            APSR.N = result<31>;
9055            APSR.Z = IsZeroBit(result);
9056            APSR.C = carry;
9057            APSR.V = overflow;
9058#endif
9059
9060    bool success = false;
9061
9062    uint32_t Rd; // the destination register
9063    uint32_t Rn; // the first operand
9064    bool setflags;
9065    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9066    switch (encoding) {
9067    case eEncodingT1:
9068        Rd = Bits32(opcode, 2, 0);
9069        Rn = Bits32(opcode, 5, 3);
9070        setflags = !InITBlock();
9071        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9072        break;
9073    case eEncodingT2:
9074        Rd = Rn = Bits32(opcode, 10, 8);
9075        setflags = !InITBlock();
9076        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9077        break;
9078    case eEncodingT3:
9079        Rd = Bits32(opcode, 11, 8);
9080        Rn = Bits32(opcode, 19, 16);
9081        setflags = BitIsSet(opcode, 20);
9082        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9083
9084        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9085        if (Rd == 15 && setflags)
9086            return EmulateCMPImm (opcode, eEncodingT2);
9087
9088        // if Rn == '1101' then SEE SUB (SP minus immediate);
9089        if (Rn == 13)
9090            return EmulateSUBSPImm (opcode, eEncodingT2);
9091
9092        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9093        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9094            return false;
9095        break;
9096    case eEncodingT4:
9097        Rd = Bits32(opcode, 11, 8);
9098        Rn = Bits32(opcode, 19, 16);
9099        setflags = BitIsSet(opcode, 20);
9100        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9101
9102        // if Rn == '1111' then SEE ADR;
9103        if (Rn == 15)
9104            return EmulateADR (opcode, eEncodingT2);
9105
9106        // if Rn == '1101' then SEE SUB (SP minus immediate);
9107        if (Rn == 13)
9108            return EmulateSUBSPImm (opcode, eEncodingT3);
9109
9110        if (BadReg(Rd))
9111            return false;
9112        break;
9113    default:
9114        return false;
9115    }
9116    // Read the register value from the operand register Rn.
9117    uint32_t reg_val = ReadCoreReg(Rn, &success);
9118    if (!success)
9119        return false;
9120
9121    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9122
9123    EmulateInstruction::Context context;
9124    context.type = EmulateInstruction::eContextImmediate;
9125    context.SetNoArgs ();
9126
9127    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9128        return false;
9129
9130    return true;
9131}
9132
9133// This instruction subtracts an immediate value from a register value, and writes the result
9134// to the destination register.  It can optionally update the condition flags based on the result.
9135bool
9136EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9137{
9138#if 0
9139    // ARM pseudo code...
9140    if ConditionPassed() then
9141        EncodingSpecificOperations();
9142        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9143        if d == 15 then
9144            ALUWritePC(result); // setflags is always FALSE here
9145        else
9146            R[d] = result;
9147            if setflags then
9148                APSR.N = result<31>;
9149                APSR.Z = IsZeroBit(result);
9150                APSR.C = carry;
9151                APSR.V = overflow;
9152#endif
9153
9154    bool success = false;
9155
9156    uint32_t Rd; // the destination register
9157    uint32_t Rn; // the first operand
9158    bool setflags;
9159    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9160    switch (encoding) {
9161    case eEncodingA1:
9162        Rd = Bits32(opcode, 15, 12);
9163        Rn = Bits32(opcode, 19, 16);
9164        setflags = BitIsSet(opcode, 20);
9165        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9166
9167        // if Rn == '1111' && S == '0' then SEE ADR;
9168        if (Rn == 15 && !setflags)
9169            return EmulateADR (opcode, eEncodingA2);
9170
9171        // if Rn == '1101' then SEE SUB (SP minus immediate);
9172        if (Rn == 13)
9173            return EmulateSUBSPImm (opcode, eEncodingA1);
9174
9175        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9176        if (Rd == 15 && setflags)
9177            return EmulateSUBSPcLrEtc (opcode, encoding);
9178        break;
9179    default:
9180        return false;
9181    }
9182    // Read the register value from the operand register Rn.
9183    uint32_t reg_val = ReadCoreReg(Rn, &success);
9184    if (!success)
9185        return false;
9186
9187    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9188
9189    EmulateInstruction::Context context;
9190    context.type = EmulateInstruction::eContextImmediate;
9191    context.SetNoArgs ();
9192
9193    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9194        return false;
9195
9196    return true;
9197}
9198
9199// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9200// immediate value.  It updates the condition flags based on the result, and discards the result.
9201bool
9202EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9203{
9204#if 0
9205    // ARM pseudo code...
9206    if ConditionPassed() then
9207        EncodingSpecificOperations();
9208        result = R[n] EOR imm32;
9209        APSR.N = result<31>;
9210        APSR.Z = IsZeroBit(result);
9211        APSR.C = carry;
9212        // APSR.V unchanged
9213#endif
9214
9215    bool success = false;
9216
9217    if (ConditionPassed(opcode))
9218    {
9219        uint32_t Rn;
9220        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9221        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9222        switch (encoding)
9223        {
9224        case eEncodingT1:
9225            Rn = Bits32(opcode, 19, 16);
9226            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9227            if (BadReg(Rn))
9228                return false;
9229            break;
9230        case eEncodingA1:
9231            Rn = Bits32(opcode, 19, 16);
9232            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9233            break;
9234        default:
9235            return false;
9236        }
9237
9238        // Read the first operand.
9239        uint32_t val1 = ReadCoreReg(Rn, &success);
9240        if (!success)
9241            return false;
9242
9243        uint32_t result = val1 ^ imm32;
9244
9245        EmulateInstruction::Context context;
9246        context.type = EmulateInstruction::eContextImmediate;
9247        context.SetNoArgs ();
9248
9249        if (!WriteFlags(context, result, carry))
9250            return false;
9251    }
9252    return true;
9253}
9254
9255// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9256// optionally-shifted register value.  It updates the condition flags based on the result, and discards
9257// the result.
9258bool
9259EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9260{
9261#if 0
9262    // ARM pseudo code...
9263    if ConditionPassed() then
9264        EncodingSpecificOperations();
9265        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9266        result = R[n] EOR shifted;
9267        APSR.N = result<31>;
9268        APSR.Z = IsZeroBit(result);
9269        APSR.C = carry;
9270        // APSR.V unchanged
9271#endif
9272
9273    bool success = false;
9274
9275    if (ConditionPassed(opcode))
9276    {
9277        uint32_t Rn, Rm;
9278        ARM_ShifterType shift_t;
9279        uint32_t shift_n; // the shift applied to the value read from Rm
9280        uint32_t carry;
9281        switch (encoding)
9282        {
9283        case eEncodingT1:
9284            Rn = Bits32(opcode, 19, 16);
9285            Rm = Bits32(opcode, 3, 0);
9286            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9287            if (BadReg(Rn) || BadReg(Rm))
9288                return false;
9289            break;
9290        case eEncodingA1:
9291            Rn = Bits32(opcode, 19, 16);
9292            Rm = Bits32(opcode, 3, 0);
9293            shift_n = DecodeImmShiftARM(opcode, shift_t);
9294            break;
9295        default:
9296            return false;
9297        }
9298
9299        // Read the first operand.
9300        uint32_t val1 = ReadCoreReg(Rn, &success);
9301        if (!success)
9302            return false;
9303
9304        // Read the second operand.
9305        uint32_t val2 = ReadCoreReg(Rm, &success);
9306        if (!success)
9307            return false;
9308
9309        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9310        if (!success)
9311            return false;
9312        uint32_t result = val1 ^ shifted;
9313
9314        EmulateInstruction::Context context;
9315        context.type = EmulateInstruction::eContextImmediate;
9316        context.SetNoArgs ();
9317
9318        if (!WriteFlags(context, result, carry))
9319            return false;
9320    }
9321    return true;
9322}
9323
9324// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9325// It updates the condition flags based on the result, and discards the result.
9326bool
9327EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9328{
9329#if 0
9330    // ARM pseudo code...
9331    if ConditionPassed() then
9332        EncodingSpecificOperations();
9333        result = R[n] AND imm32;
9334        APSR.N = result<31>;
9335        APSR.Z = IsZeroBit(result);
9336        APSR.C = carry;
9337        // APSR.V unchanged
9338#endif
9339
9340    bool success = false;
9341
9342    if (ConditionPassed(opcode))
9343    {
9344        uint32_t Rn;
9345        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9346        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9347        switch (encoding)
9348        {
9349        case eEncodingT1:
9350            Rn = Bits32(opcode, 19, 16);
9351            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9352            if (BadReg(Rn))
9353                return false;
9354            break;
9355        case eEncodingA1:
9356            Rn = Bits32(opcode, 19, 16);
9357            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9358            break;
9359        default:
9360            return false;
9361        }
9362
9363        // Read the first operand.
9364        uint32_t val1 = ReadCoreReg(Rn, &success);
9365        if (!success)
9366            return false;
9367
9368        uint32_t result = val1 & imm32;
9369
9370        EmulateInstruction::Context context;
9371        context.type = EmulateInstruction::eContextImmediate;
9372        context.SetNoArgs ();
9373
9374        if (!WriteFlags(context, result, carry))
9375            return false;
9376    }
9377    return true;
9378}
9379
9380// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9381// It updates the condition flags based on the result, and discards the result.
9382bool
9383EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9384{
9385#if 0
9386    // ARM pseudo code...
9387    if ConditionPassed() then
9388        EncodingSpecificOperations();
9389        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9390        result = R[n] AND shifted;
9391        APSR.N = result<31>;
9392        APSR.Z = IsZeroBit(result);
9393        APSR.C = carry;
9394        // APSR.V unchanged
9395#endif
9396
9397    bool success = false;
9398
9399    if (ConditionPassed(opcode))
9400    {
9401        uint32_t Rn, Rm;
9402        ARM_ShifterType shift_t;
9403        uint32_t shift_n; // the shift applied to the value read from Rm
9404        uint32_t carry;
9405        switch (encoding)
9406        {
9407        case eEncodingT1:
9408            Rn = Bits32(opcode, 2, 0);
9409            Rm = Bits32(opcode, 5, 3);
9410            shift_t = SRType_LSL;
9411            shift_n = 0;
9412            break;
9413        case eEncodingT2:
9414            Rn = Bits32(opcode, 19, 16);
9415            Rm = Bits32(opcode, 3, 0);
9416            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9417            if (BadReg(Rn) || BadReg(Rm))
9418                return false;
9419            break;
9420        case eEncodingA1:
9421            Rn = Bits32(opcode, 19, 16);
9422            Rm = Bits32(opcode, 3, 0);
9423            shift_n = DecodeImmShiftARM(opcode, shift_t);
9424            break;
9425        default:
9426            return false;
9427        }
9428
9429        // Read the first operand.
9430        uint32_t val1 = ReadCoreReg(Rn, &success);
9431        if (!success)
9432            return false;
9433
9434        // Read the second operand.
9435        uint32_t val2 = ReadCoreReg(Rm, &success);
9436        if (!success)
9437            return false;
9438
9439        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9440        if (!success)
9441            return false;
9442        uint32_t result = val1 & shifted;
9443
9444        EmulateInstruction::Context context;
9445        context.type = EmulateInstruction::eContextImmediate;
9446        context.SetNoArgs ();
9447
9448        if (!WriteFlags(context, result, carry))
9449            return false;
9450    }
9451    return true;
9452}
9453
9454// A8.6.216 SUB (SP minus register)
9455bool
9456EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9457{
9458#if 0
9459    if ConditionPassed() then
9460        EncodingSpecificOperations();
9461        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9462        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9463        if d == 15 then // Can only occur for ARM encoding
9464            ALUWritePC(result); // setflags is always FALSE here
9465        else
9466            R[d] = result;
9467            if setflags then
9468                APSR.N = result<31>;
9469                APSR.Z = IsZeroBit(result);
9470                APSR.C = carry;
9471                APSR.V = overflow;
9472#endif
9473
9474    bool success = false;
9475
9476    if (ConditionPassed(opcode))
9477    {
9478        uint32_t d;
9479        uint32_t m;
9480        bool setflags;
9481        ARM_ShifterType shift_t;
9482        uint32_t shift_n;
9483
9484        switch (encoding)
9485        {
9486            case eEncodingT1:
9487                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9488                d = Bits32 (opcode, 11, 8);
9489                m = Bits32 (opcode, 3, 0);
9490                setflags = BitIsSet (opcode, 20);
9491
9492                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9493                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9494
9495                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9496                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9497                    return false;
9498
9499                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9500                if ((d == 15) || BadReg (m))
9501                    return false;
9502                break;
9503
9504            case eEncodingA1:
9505                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9506                d = Bits32 (opcode, 15, 12);
9507                m = Bits32 (opcode, 3, 0);
9508                setflags = BitIsSet (opcode, 20);
9509
9510                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9511                if (d == 15 && setflags)
9512                    EmulateSUBSPcLrEtc (opcode, encoding);
9513
9514                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9515                shift_n = DecodeImmShiftARM (opcode, shift_t);
9516                break;
9517
9518            default:
9519                return false;
9520        }
9521
9522        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9523        uint32_t Rm = ReadCoreReg (m, &success);
9524        if (!success)
9525            return false;
9526
9527        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9528        if (!success)
9529            return false;
9530
9531        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9532        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9533        if (!success)
9534            return false;
9535
9536        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9537
9538        EmulateInstruction::Context context;
9539        context.type = eContextArithmetic;
9540        RegisterInfo sp_reg;
9541        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9542        RegisterInfo dwarf_reg;
9543        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9544        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9545
9546        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9547            return false;
9548    }
9549    return true;
9550}
9551
9552
9553// A8.6.7 ADD (register-shifted register)
9554bool
9555EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9556{
9557#if 0
9558    if ConditionPassed() then
9559        EncodingSpecificOperations();
9560        shift_n = UInt(R[s]<7:0>);
9561        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9562        (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9563        R[d] = result;
9564        if setflags then
9565            APSR.N = result<31>;
9566            APSR.Z = IsZeroBit(result);
9567            APSR.C = carry;
9568            APSR.V = overflow;
9569#endif
9570
9571    bool success = false;
9572
9573    if (ConditionPassed(opcode))
9574    {
9575        uint32_t d;
9576        uint32_t n;
9577        uint32_t m;
9578        uint32_t s;
9579        bool setflags;
9580        ARM_ShifterType shift_t;
9581
9582        switch (encoding)
9583        {
9584            case eEncodingA1:
9585                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9586                d = Bits32 (opcode, 15, 12);
9587                n = Bits32 (opcode, 19, 16);
9588                m = Bits32 (opcode, 3, 0);
9589                s = Bits32 (opcode, 11, 8);
9590
9591                // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9592                setflags = BitIsSet (opcode, 20);
9593                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9594
9595                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9596                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9597                    return false;
9598                break;
9599
9600            default:
9601                return false;
9602        }
9603
9604        // shift_n = UInt(R[s]<7:0>);
9605        uint32_t Rs = ReadCoreReg (s, &success);
9606        if (!success)
9607            return false;
9608
9609        uint32_t shift_n = Bits32 (Rs, 7, 0);
9610
9611        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9612        uint32_t Rm = ReadCoreReg (m, &success);
9613        if (!success)
9614            return false;
9615
9616        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9617        if (!success)
9618            return false;
9619
9620        // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9621        uint32_t Rn = ReadCoreReg (n, &success);
9622        if (!success)
9623            return false;
9624
9625        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9626
9627        // R[d] = result;
9628        EmulateInstruction::Context context;
9629        context.type = eContextArithmetic;
9630        RegisterInfo reg_n;
9631        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9632        RegisterInfo reg_m;
9633        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9634
9635        context.SetRegisterRegisterOperands (reg_n, reg_m);
9636
9637        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9638            return false;
9639
9640        // if setflags then
9641            // APSR.N = result<31>;
9642            // APSR.Z = IsZeroBit(result);
9643            // APSR.C = carry;
9644            // APSR.V = overflow;
9645        if (setflags)
9646            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9647    }
9648    return true;
9649}
9650
9651// A8.6.213 SUB (register)
9652bool
9653EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9654{
9655#if 0
9656    if ConditionPassed() then
9657        EncodingSpecificOperations();
9658        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9659        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9660        if d == 15 then // Can only occur for ARM encoding
9661            ALUWritePC(result); // setflags is always FALSE here
9662        else
9663            R[d] = result;
9664            if setflags then
9665                APSR.N = result<31>;
9666                APSR.Z = IsZeroBit(result);
9667                APSR.C = carry;
9668                APSR.V = overflow;
9669#endif
9670
9671    bool success = false;
9672
9673    if (ConditionPassed(opcode))
9674    {
9675        uint32_t d;
9676        uint32_t n;
9677        uint32_t m;
9678        bool setflags;
9679        ARM_ShifterType shift_t;
9680        uint32_t shift_n;
9681
9682        switch (encoding)
9683        {
9684            case eEncodingT1:
9685                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9686                d = Bits32 (opcode, 2, 0);
9687                n = Bits32 (opcode, 5, 3);
9688                m = Bits32 (opcode, 8, 6);
9689                setflags = !InITBlock();
9690
9691                // (shift_t, shift_n) = (SRType_LSL, 0);
9692                shift_t = SRType_LSL;
9693                shift_n = 0;
9694
9695                break;
9696
9697            case eEncodingT2:
9698                // if Rd == �1111� && S == �1� then SEE CMP (register);
9699                // if Rn == �1101� then SEE SUB (SP minus register);
9700                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9701                d = Bits32 (opcode, 11, 8);
9702                n = Bits32 (opcode, 19, 16);
9703                m = Bits32 (opcode, 3, 0);
9704                setflags = BitIsSet (opcode, 20);
9705
9706                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9707                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9708
9709                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9710                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9711                    return false;
9712
9713                break;
9714
9715            case eEncodingA1:
9716                // if Rn == �1101� then SEE SUB (SP minus register);
9717                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9718                d = Bits32 (opcode, 15, 12);
9719                n = Bits32 (opcode, 19, 16);
9720                m = Bits32 (opcode, 3, 0);
9721                setflags = BitIsSet (opcode, 20);
9722
9723                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9724                if ((d == 15) && setflags)
9725                    EmulateSUBSPcLrEtc (opcode, encoding);
9726
9727                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9728                shift_n = DecodeImmShiftARM (opcode, shift_t);
9729
9730                break;
9731
9732            default:
9733                return false;
9734        }
9735
9736        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9737        uint32_t Rm = ReadCoreReg (m, &success);
9738        if (!success)
9739            return false;
9740
9741        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9742        if (!success)
9743            return false;
9744
9745        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9746        uint32_t Rn = ReadCoreReg (n, &success);
9747        if (!success)
9748            return false;
9749
9750        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9751
9752        // if d == 15 then // Can only occur for ARM encoding
9753            // ALUWritePC(result); // setflags is always FALSE here
9754        // else
9755            // R[d] = result;
9756            // if setflags then
9757                // APSR.N = result<31>;
9758                // APSR.Z = IsZeroBit(result);
9759                // APSR.C = carry;
9760                // APSR.V = overflow;
9761
9762        EmulateInstruction::Context context;
9763        context.type = eContextArithmetic;
9764        RegisterInfo reg_n;
9765        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9766        RegisterInfo reg_m;
9767        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9768        context.SetRegisterRegisterOperands (reg_n, reg_m);
9769
9770        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9771            return false;
9772    }
9773    return true;
9774}
9775
9776// A8.6.202 STREX
9777// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9778// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9779bool
9780EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9781{
9782#if 0
9783    if ConditionPassed() then
9784        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9785        address = R[n] + imm32;
9786        if ExclusiveMonitorsPass(address,4) then
9787            MemA[address,4] = R[t];
9788            R[d] = 0;
9789        else
9790            R[d] = 1;
9791#endif
9792
9793    bool success = false;
9794
9795    if (ConditionPassed(opcode))
9796    {
9797        uint32_t d;
9798        uint32_t t;
9799        uint32_t n;
9800        uint32_t imm32;
9801        const uint32_t addr_byte_size = GetAddressByteSize();
9802
9803        switch (encoding)
9804        {
9805            case eEncodingT1:
9806                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9807                d = Bits32 (opcode, 11, 8);
9808                t = Bits32 (opcode, 15, 12);
9809                n = Bits32 (opcode, 19, 16);
9810                imm32 = Bits32 (opcode, 7, 0) << 2;
9811
9812                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9813                if (BadReg (d) || BadReg (t) || (n == 15))
9814                  return false;
9815
9816                // if d == n || d == t then UNPREDICTABLE;
9817                if ((d == n) || (d == t))
9818                  return false;
9819
9820                break;
9821
9822            case eEncodingA1:
9823                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9824                d = Bits32 (opcode, 15, 12);
9825                t = Bits32 (opcode, 3, 0);
9826                n = Bits32 (opcode, 19, 16);
9827                imm32 = 0;
9828
9829                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9830                if ((d == 15) || (t == 15) || (n == 15))
9831                    return false;
9832
9833                // if d == n || d == t then UNPREDICTABLE;
9834                if ((d == n) || (d == t))
9835                    return false;
9836
9837                break;
9838
9839            default:
9840                return false;
9841        }
9842
9843        // address = R[n] + imm32;
9844        uint32_t Rn = ReadCoreReg (n, &success);
9845        if (!success)
9846            return false;
9847
9848        addr_t address = Rn + imm32;
9849
9850        RegisterInfo base_reg;
9851        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9852        RegisterInfo data_reg;
9853        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9854        EmulateInstruction::Context context;
9855        context.type = eContextRegisterStore;
9856        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9857
9858        // if ExclusiveMonitorsPass(address,4) then
9859        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9860        //                                                         always return true.
9861        if (true)
9862        {
9863            // MemA[address,4] = R[t];
9864            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9865            if (!success)
9866                return false;
9867
9868            if (!MemAWrite (context, address, Rt, addr_byte_size))
9869                return false;
9870
9871            // R[d] = 0;
9872            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9873                return false;
9874        }
9875        else
9876        {
9877            // R[d] = 1;
9878            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9879                return false;
9880        }
9881    }
9882    return true;
9883}
9884
9885// A8.6.197 STRB (immediate, ARM)
9886bool
9887EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9888{
9889#if 0
9890    if ConditionPassed() then
9891        EncodingSpecificOperations();
9892        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9893        address = if index then offset_addr else R[n];
9894        MemU[address,1] = R[t]<7:0>;
9895        if wback then R[n] = offset_addr;
9896#endif
9897
9898    bool success = false;
9899
9900    if (ConditionPassed(opcode))
9901    {
9902        uint32_t t;
9903        uint32_t n;
9904        uint32_t imm32;
9905        bool index;
9906        bool add;
9907        bool wback;
9908
9909        switch (encoding)
9910        {
9911            case eEncodingA1:
9912                // if P == �0� && W == �1� then SEE STRBT;
9913                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9914                t = Bits32 (opcode, 15, 12);
9915                n = Bits32 (opcode, 19, 16);
9916                imm32 = Bits32 (opcode, 11, 0);
9917
9918                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9919                index = BitIsSet (opcode, 24);
9920                add = BitIsSet (opcode, 23);
9921                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9922
9923                // if t == 15 then UNPREDICTABLE;
9924                if (t == 15)
9925                    return false;
9926
9927                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9928                if (wback && ((n == 15) || (n == t)))
9929                    return false;
9930
9931                break;
9932
9933            default:
9934                return false;
9935        }
9936
9937        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9938        uint32_t Rn = ReadCoreReg (n, &success);
9939        if (!success)
9940            return false;
9941
9942        addr_t offset_addr;
9943        if (add)
9944            offset_addr = Rn + imm32;
9945        else
9946            offset_addr = Rn - imm32;
9947
9948        // address = if index then offset_addr else R[n];
9949        addr_t address;
9950        if (index)
9951            address = offset_addr;
9952        else
9953            address = Rn;
9954
9955        // MemU[address,1] = R[t]<7:0>;
9956        uint32_t Rt = ReadCoreReg (t, &success);
9957        if (!success)
9958            return false;
9959
9960        RegisterInfo base_reg;
9961        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9962        RegisterInfo data_reg;
9963        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9964        EmulateInstruction::Context context;
9965        context.type = eContextRegisterStore;
9966        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9967
9968        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9969            return false;
9970
9971        // if wback then R[n] = offset_addr;
9972        if (wback)
9973        {
9974            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9975                return false;
9976        }
9977    }
9978    return true;
9979}
9980
9981// A8.6.194 STR (immediate, ARM)
9982bool
9983EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9984{
9985#if 0
9986    if ConditionPassed() then
9987        EncodingSpecificOperations();
9988        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9989        address = if index then offset_addr else R[n];
9990        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9991        if wback then R[n] = offset_addr;
9992#endif
9993
9994    bool success = false;
9995
9996    if (ConditionPassed(opcode))
9997    {
9998        uint32_t t;
9999        uint32_t n;
10000        uint32_t imm32;
10001        bool index;
10002        bool add;
10003        bool wback;
10004
10005        const uint32_t addr_byte_size = GetAddressByteSize();
10006
10007        switch (encoding)
10008        {
10009            case eEncodingA1:
10010                // if P == �0� && W == �1� then SEE STRT;
10011                // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
10012                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10013                t = Bits32 (opcode, 15, 12);
10014                n = Bits32 (opcode, 19, 16);
10015                imm32 = Bits32 (opcode, 11, 0);
10016
10017                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10018                index = BitIsSet (opcode, 24);
10019                add = BitIsSet (opcode, 23);
10020                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10021
10022                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10023                if (wback && ((n == 15) || (n == t)))
10024                    return false;
10025
10026                break;
10027
10028            default:
10029                return false;
10030        }
10031
10032        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10033        uint32_t Rn = ReadCoreReg (n, &success);
10034        if (!success)
10035            return false;
10036
10037        addr_t offset_addr;
10038        if (add)
10039            offset_addr = Rn + imm32;
10040        else
10041            offset_addr = Rn - imm32;
10042
10043        // address = if index then offset_addr else R[n];
10044        addr_t address;
10045        if (index)
10046            address = offset_addr;
10047        else
10048            address = Rn;
10049
10050        RegisterInfo base_reg;
10051        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10052        RegisterInfo data_reg;
10053        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10054        EmulateInstruction::Context context;
10055        context.type = eContextRegisterStore;
10056        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10057
10058        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10059        uint32_t Rt = ReadCoreReg (t, &success);
10060        if (!success)
10061            return false;
10062
10063        if (t == 15)
10064        {
10065            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10066            if (!success)
10067                return false;
10068
10069            if (!MemUWrite (context, address, pc_value, addr_byte_size))
10070                return false;
10071        }
10072        else
10073        {
10074            if (!MemUWrite (context, address, Rt, addr_byte_size))
10075                  return false;
10076        }
10077
10078        // if wback then R[n] = offset_addr;
10079        if (wback)
10080        {
10081            context.type = eContextAdjustBaseRegister;
10082            context.SetImmediate (offset_addr);
10083
10084            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10085                return false;
10086        }
10087    }
10088    return true;
10089}
10090
10091// A8.6.66 LDRD (immediate)
10092// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10093// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10094bool
10095EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10096{
10097#if 0
10098    if ConditionPassed() then
10099        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10100        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10101        address = if index then offset_addr else R[n];
10102        R[t] = MemA[address,4];
10103        R[t2] = MemA[address+4,4];
10104        if wback then R[n] = offset_addr;
10105#endif
10106
10107    bool success = false;
10108
10109    if (ConditionPassed(opcode))
10110    {
10111        uint32_t t;
10112        uint32_t t2;
10113        uint32_t n;
10114        uint32_t imm32;
10115        bool index;
10116        bool add;
10117        bool wback;
10118
10119        switch (encoding)
10120        {
10121            case eEncodingT1:
10122                //if P == �0� && W == �0� then SEE �Related encodings�;
10123                //if Rn == �1111� then SEE LDRD (literal);
10124                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10125                t = Bits32 (opcode, 15, 12);
10126                t2 = Bits32 (opcode, 11, 8);
10127                n = Bits32 (opcode, 19, 16);
10128                imm32 = Bits32 (opcode, 7, 0) << 2;
10129
10130                //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10131                index = BitIsSet (opcode, 24);
10132                add = BitIsSet (opcode, 23);
10133                wback = BitIsSet (opcode, 21);
10134
10135                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10136                if (wback && ((n == t) || (n == t2)))
10137                    return false;
10138
10139                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10140                if (BadReg (t) || BadReg (t2) || (t == t2))
10141                    return false;
10142
10143                break;
10144
10145            case eEncodingA1:
10146                //if Rn == �1111� then SEE LDRD (literal);
10147                //if Rt<0> == �1� then UNPREDICTABLE;
10148                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10149                t = Bits32 (opcode, 15, 12);
10150                if (BitIsSet (t, 0))
10151                    return false;
10152                t2 = t + 1;
10153                n = Bits32 (opcode, 19, 16);
10154                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10155
10156                //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10157                index = BitIsSet (opcode, 24);
10158                add = BitIsSet (opcode, 23);
10159                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10160
10161                //if P == �0� && W == �1� then UNPREDICTABLE;
10162                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10163                    return false;
10164
10165                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10166                if (wback && ((n == t) || (n == t2)))
10167                    return false;
10168
10169                //if t2 == 15 then UNPREDICTABLE;
10170                if (t2 == 15)
10171                    return false;
10172
10173                break;
10174
10175            default:
10176                return false;
10177        }
10178
10179        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10180        uint32_t Rn = ReadCoreReg (n, &success);
10181        if (!success)
10182            return false;
10183
10184        addr_t offset_addr;
10185        if (add)
10186                  offset_addr = Rn + imm32;
10187        else
10188            offset_addr = Rn - imm32;
10189
10190        //address = if index then offset_addr else R[n];
10191        addr_t address;
10192        if (index)
10193            address = offset_addr;
10194        else
10195            address = Rn;
10196
10197        //R[t] = MemA[address,4];
10198        RegisterInfo base_reg;
10199        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10200
10201        EmulateInstruction::Context context;
10202        context.type = eContextRegisterLoad;
10203        context.SetRegisterPlusOffset (base_reg, address - Rn);
10204
10205        const uint32_t addr_byte_size = GetAddressByteSize();
10206        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10207        if (!success)
10208            return false;
10209
10210        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10211            return false;
10212
10213        //R[t2] = MemA[address+4,4];
10214
10215        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10216        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10217        if (!success)
10218            return false;
10219
10220        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10221            return false;
10222
10223        //if wback then R[n] = offset_addr;
10224        if (wback)
10225        {
10226            context.type = eContextAdjustBaseRegister;
10227            context.SetAddress (offset_addr);
10228
10229            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10230                return false;
10231        }
10232    }
10233    return true;
10234}
10235
10236// A8.6.68 LDRD (register)
10237// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10238// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10239bool
10240EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10241{
10242#if 0
10243    if ConditionPassed() then
10244        EncodingSpecificOperations();
10245        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10246        address = if index then offset_addr else R[n];
10247        R[t] = MemA[address,4];
10248        R[t2] = MemA[address+4,4];
10249        if wback then R[n] = offset_addr;
10250#endif
10251
10252    bool success = false;
10253
10254    if (ConditionPassed(opcode))
10255    {
10256        uint32_t t;
10257        uint32_t t2;
10258        uint32_t n;
10259        uint32_t m;
10260        bool index;
10261        bool add;
10262        bool wback;
10263
10264        switch (encoding)
10265        {
10266            case eEncodingA1:
10267                // if Rt<0> == �1� then UNPREDICTABLE;
10268                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10269                t = Bits32 (opcode, 15, 12);
10270                if (BitIsSet (t, 0))
10271                    return false;
10272                t2 = t + 1;
10273                n = Bits32 (opcode, 19, 16);
10274                m = Bits32 (opcode, 3, 0);
10275
10276                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10277                index = BitIsSet (opcode, 24);
10278                add = BitIsSet (opcode, 23);
10279                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10280
10281                // if P == �0� && W == �1� then UNPREDICTABLE;
10282                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10283                  return false;
10284
10285                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10286                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10287                  return false;
10288
10289                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10290                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10291                  return false;
10292
10293                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10294                if ((ArchVersion() < 6) && wback && (m == n))
10295                  return false;
10296                break;
10297
10298            default:
10299                return false;
10300        }
10301
10302        uint32_t Rn = ReadCoreReg (n, &success);
10303        if (!success)
10304            return false;
10305        RegisterInfo base_reg;
10306        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10307
10308        uint32_t Rm = ReadCoreReg (m, &success);
10309        if (!success)
10310            return false;
10311        RegisterInfo offset_reg;
10312        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10313
10314        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10315        addr_t offset_addr;
10316        if (add)
10317            offset_addr = Rn + Rm;
10318        else
10319            offset_addr = Rn - Rm;
10320
10321        // address = if index then offset_addr else R[n];
10322        addr_t address;
10323        if (index)
10324            address = offset_addr;
10325        else
10326            address = Rn;
10327
10328        EmulateInstruction::Context context;
10329        context.type = eContextRegisterLoad;
10330        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10331
10332        // R[t] = MemA[address,4];
10333        const uint32_t addr_byte_size = GetAddressByteSize();
10334        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10335        if (!success)
10336            return false;
10337
10338        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10339            return false;
10340
10341        // R[t2] = MemA[address+4,4];
10342
10343        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10344        if (!success)
10345            return false;
10346
10347        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10348            return false;
10349
10350        // if wback then R[n] = offset_addr;
10351        if (wback)
10352        {
10353            context.type = eContextAdjustBaseRegister;
10354            context.SetAddress (offset_addr);
10355
10356            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10357                return false;
10358        }
10359    }
10360    return true;
10361}
10362
10363// A8.6.200 STRD (immediate)
10364// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10365// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10366bool
10367EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10368{
10369#if 0
10370    if ConditionPassed() then
10371        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10372        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10373        address = if index then offset_addr else R[n];
10374        MemA[address,4] = R[t];
10375        MemA[address+4,4] = R[t2];
10376        if wback then R[n] = offset_addr;
10377#endif
10378
10379    bool success = false;
10380
10381    if (ConditionPassed(opcode))
10382    {
10383        uint32_t t;
10384        uint32_t t2;
10385        uint32_t n;
10386        uint32_t imm32;
10387        bool index;
10388        bool add;
10389        bool wback;
10390
10391        switch (encoding)
10392        {
10393            case eEncodingT1:
10394                // if P == �0� && W == �0� then SEE �Related encodings�;
10395                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10396                t = Bits32 (opcode, 15, 12);
10397                t2 = Bits32 (opcode, 11, 8);
10398                n = Bits32 (opcode, 19, 16);
10399                imm32 = Bits32 (opcode, 7, 0) << 2;
10400
10401                // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10402                index = BitIsSet (opcode, 24);
10403                add = BitIsSet (opcode, 23);
10404                wback = BitIsSet (opcode, 21);
10405
10406                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10407                if (wback && ((n == t) || (n == t2)))
10408                    return false;
10409
10410                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10411                if ((n == 15) || BadReg (t) || BadReg (t2))
10412                    return false;
10413
10414                break;
10415
10416            case eEncodingA1:
10417                // if Rt<0> == �1� then UNPREDICTABLE;
10418                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10419                t = Bits32 (opcode, 15, 12);
10420                if (BitIsSet (t, 0))
10421                    return false;
10422
10423                t2 = t + 1;
10424                n = Bits32 (opcode, 19, 16);
10425                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10426
10427                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10428                index = BitIsSet (opcode, 24);
10429                add = BitIsSet (opcode, 23);
10430                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10431
10432                // if P == �0� && W == �1� then UNPREDICTABLE;
10433                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10434                    return false;
10435
10436                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10437                if (wback && ((n == 15) || (n == t) || (n == t2)))
10438                    return false;
10439
10440                // if t2 == 15 then UNPREDICTABLE;
10441                if (t2 == 15)
10442                    return false;
10443
10444                break;
10445
10446            default:
10447                return false;
10448        }
10449
10450        RegisterInfo base_reg;
10451        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10452
10453        uint32_t Rn = ReadCoreReg (n, &success);
10454        if (!success)
10455            return false;
10456
10457        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10458        addr_t offset_addr;
10459        if (add)
10460            offset_addr = Rn + imm32;
10461        else
10462            offset_addr = Rn - imm32;
10463
10464        //address = if index then offset_addr else R[n];
10465        addr_t address;
10466        if (index)
10467            address = offset_addr;
10468        else
10469            address = Rn;
10470
10471        //MemA[address,4] = R[t];
10472        RegisterInfo data_reg;
10473        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10474
10475        uint32_t data = ReadCoreReg (t, &success);
10476        if (!success)
10477            return false;
10478
10479        EmulateInstruction::Context context;
10480        context.type = eContextRegisterStore;
10481        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10482
10483        const uint32_t addr_byte_size = GetAddressByteSize();
10484
10485        if (!MemAWrite (context, address, data, addr_byte_size))
10486            return false;
10487
10488        //MemA[address+4,4] = R[t2];
10489        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10490        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10491
10492        data = ReadCoreReg (t2, &success);
10493        if (!success)
10494            return false;
10495
10496        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10497            return false;
10498
10499        //if wback then R[n] = offset_addr;
10500        if (wback)
10501        {
10502            context.type = eContextAdjustBaseRegister;
10503            context.SetAddress (offset_addr);
10504
10505            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10506                return false;
10507        }
10508    }
10509    return true;
10510}
10511
10512
10513// A8.6.201 STRD (register)
10514bool
10515EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10516{
10517#if 0
10518    if ConditionPassed() then
10519        EncodingSpecificOperations();
10520        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10521        address = if index then offset_addr else R[n];
10522        MemA[address,4] = R[t];
10523        MemA[address+4,4] = R[t2];
10524        if wback then R[n] = offset_addr;
10525#endif
10526
10527    bool success = false;
10528
10529    if (ConditionPassed(opcode))
10530    {
10531        uint32_t t;
10532        uint32_t t2;
10533        uint32_t n;
10534        uint32_t m;
10535        bool index;
10536        bool add;
10537        bool wback;
10538
10539        switch (encoding)
10540        {
10541            case eEncodingA1:
10542                // if Rt<0> == �1� then UNPREDICTABLE;
10543                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10544                t = Bits32 (opcode, 15, 12);
10545                if (BitIsSet (t, 0))
10546                   return false;
10547
10548                t2 = t+1;
10549                n = Bits32 (opcode, 19, 16);
10550                m = Bits32 (opcode, 3, 0);
10551
10552                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10553                index = BitIsSet (opcode, 24);
10554                add = BitIsSet (opcode, 23);
10555                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10556
10557                // if P == �0� && W == �1� then UNPREDICTABLE;
10558                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10559                   return false;
10560
10561                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10562                if ((t2 == 15) || (m == 15))
10563                   return false;
10564
10565                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10566                if (wback && ((n == 15) || (n == t) || (n == t2)))
10567                   return false;
10568
10569                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10570                if ((ArchVersion() < 6) && wback && (m == n))
10571                   return false;
10572
10573                break;
10574
10575            default:
10576                return false;
10577        }
10578
10579        RegisterInfo base_reg;
10580        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10581        RegisterInfo offset_reg;
10582        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10583        RegisterInfo data_reg;
10584
10585        uint32_t Rn = ReadCoreReg (n, &success);
10586        if (!success)
10587            return false;
10588
10589        uint32_t Rm = ReadCoreReg (m, &success);
10590        if (!success)
10591            return false;
10592
10593        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10594        addr_t offset_addr;
10595        if (add)
10596            offset_addr = Rn + Rm;
10597        else
10598            offset_addr = Rn - Rm;
10599
10600        // address = if index then offset_addr else R[n];
10601        addr_t address;
10602        if (index)
10603            address = offset_addr;
10604        else
10605            address = Rn;
10606                          // MemA[address,4] = R[t];
10607        uint32_t Rt = ReadCoreReg (t, &success);
10608        if (!success)
10609            return false;
10610
10611        EmulateInstruction::Context context;
10612        context.type = eContextRegisterStore;
10613        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10614        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10615
10616        const uint32_t addr_byte_size = GetAddressByteSize();
10617
10618        if (!MemAWrite (context, address, Rt, addr_byte_size))
10619            return false;
10620
10621        // MemA[address+4,4] = R[t2];
10622        uint32_t Rt2 = ReadCoreReg (t2, &success);
10623        if (!success)
10624            return false;
10625
10626        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10627
10628        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10629
10630        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10631            return false;
10632
10633        // if wback then R[n] = offset_addr;
10634        if (wback)
10635        {
10636            context.type = eContextAdjustBaseRegister;
10637            context.SetAddress (offset_addr);
10638
10639            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10640                return false;
10641
10642        }
10643    }
10644    return true;
10645}
10646
10647// A8.6.319 VLDM
10648// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10649// an ARM core register.
10650bool
10651EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10652{
10653#if 0
10654    if ConditionPassed() then
10655        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10656        address = if add then R[n] else R[n]-imm32;
10657        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10658        for r = 0 to regs-1
10659            if single_regs then
10660                S[d+r] = MemA[address,4]; address = address+4;
10661            else
10662                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10663                // Combine the word-aligned words in the correct order for current endianness.
10664                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10665#endif
10666
10667    bool success = false;
10668
10669    if (ConditionPassed(opcode))
10670    {
10671        bool single_regs;
10672        bool add;
10673        bool wback;
10674        uint32_t d;
10675        uint32_t n;
10676        uint32_t imm32;
10677        uint32_t regs;
10678
10679        switch (encoding)
10680        {
10681            case eEncodingT1:
10682            case eEncodingA1:
10683                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10684                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10685                // if P == �1� && W == �0� then SEE VLDR;
10686                // if P == U && W == �1� then UNDEFINED;
10687                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10688                    return false;
10689
10690                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10691                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10692                single_regs = false;
10693                add = BitIsSet (opcode, 23);
10694                wback = BitIsSet (opcode, 21);
10695
10696                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10697                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10698                n = Bits32 (opcode, 19, 16);
10699                imm32 = Bits32 (opcode, 7, 0) << 2;
10700
10701                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10702                regs = Bits32 (opcode, 7, 0) / 2;
10703
10704                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10705                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10706                    return false;
10707
10708                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10709                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10710                    return false;
10711
10712                break;
10713
10714            case eEncodingT2:
10715            case eEncodingA2:
10716                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10717                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10718                // if P == �1� && W == �0� then SEE VLDR;
10719                // if P == U && W == �1� then UNDEFINED;
10720                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10721                    return false;
10722
10723                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10724                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10725                single_regs = true;
10726                add = BitIsSet (opcode, 23);
10727                wback = BitIsSet (opcode, 21);
10728                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10729                n = Bits32 (opcode, 19, 16);
10730
10731                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10732                imm32 = Bits32 (opcode, 7, 0) << 2;
10733                regs = Bits32 (opcode, 7, 0);
10734
10735                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10736                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10737                    return false;
10738
10739                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10740                if ((regs == 0) || ((d + regs) > 32))
10741                    return false;
10742                break;
10743
10744            default:
10745                return false;
10746        }
10747
10748        RegisterInfo base_reg;
10749        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10750
10751        uint32_t Rn = ReadCoreReg (n, &success);
10752        if (!success)
10753            return false;
10754
10755        // address = if add then R[n] else R[n]-imm32;
10756        addr_t address;
10757        if (add)
10758            address = Rn;
10759        else
10760            address = Rn - imm32;
10761
10762        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10763        EmulateInstruction::Context context;
10764
10765        if (wback)
10766        {
10767            uint32_t value;
10768            if (add)
10769                value = Rn + imm32;
10770            else
10771                value = Rn - imm32;
10772
10773            context.type = eContextAdjustBaseRegister;
10774            context.SetImmediateSigned (value - Rn);
10775            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10776                return false;
10777
10778        }
10779
10780        const uint32_t addr_byte_size = GetAddressByteSize();
10781        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10782
10783        context.type = eContextRegisterLoad;
10784
10785        // for r = 0 to regs-1
10786        for (uint32_t r = 0; r < regs; ++r)
10787        {
10788            if (single_regs)
10789            {
10790                // S[d+r] = MemA[address,4]; address = address+4;
10791                context.SetRegisterPlusOffset (base_reg, address - Rn);
10792
10793                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10794                if (!success)
10795                    return false;
10796
10797                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10798                    return false;
10799
10800                address = address + 4;
10801            }
10802            else
10803            {
10804                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10805                context.SetRegisterPlusOffset (base_reg, address - Rn);
10806                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10807                if (!success)
10808                    return false;
10809
10810                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10811                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10812                if (!success)
10813                    return false;
10814
10815                address = address + 8;
10816                // // Combine the word-aligned words in the correct order for current endianness.
10817                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10818                uint64_t data;
10819                if (GetByteOrder() == eByteOrderBig)
10820                {
10821                    data = word1;
10822                    data = (data << 32) | word2;
10823                }
10824                else
10825                {
10826                    data = word2;
10827                    data = (data << 32) | word1;
10828                }
10829
10830                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10831                    return false;
10832            }
10833        }
10834    }
10835    return true;
10836}
10837
10838// A8.6.399 VSTM
10839// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10840// ARM core register.
10841bool
10842EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10843{
10844#if 0
10845    if ConditionPassed() then
10846        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10847        address = if add then R[n] else R[n]-imm32;
10848        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10849        for r = 0 to regs-1
10850            if single_regs then
10851                MemA[address,4] = S[d+r]; address = address+4;
10852            else
10853                // Store as two word-aligned words in the correct order for current endianness.
10854                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10855                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10856                address = address+8;
10857#endif
10858
10859    bool success = false;
10860
10861    if (ConditionPassed (opcode))
10862    {
10863        bool single_regs;
10864        bool add;
10865        bool wback;
10866        uint32_t d;
10867        uint32_t n;
10868        uint32_t imm32;
10869        uint32_t regs;
10870
10871        switch (encoding)
10872        {
10873            case eEncodingT1:
10874            case eEncodingA1:
10875                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10876                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10877                // if P == �1� && W == �0� then SEE VSTR;
10878                // if P == U && W == �1� then UNDEFINED;
10879                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10880                    return false;
10881
10882                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10883                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10884                single_regs = false;
10885                add = BitIsSet (opcode, 23);
10886                wback = BitIsSet (opcode, 21);
10887
10888                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10889                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10890                n = Bits32 (opcode, 19, 16);
10891                imm32 = Bits32 (opcode, 7, 0) << 2;
10892
10893                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10894                regs = Bits32 (opcode, 7, 0) / 2;
10895
10896                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10897                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10898                    return false;
10899
10900                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10901                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10902                    return false;
10903
10904                break;
10905
10906            case eEncodingT2:
10907            case eEncodingA2:
10908                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10909                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10910                // if P == �1� && W == �0� then SEE VSTR;
10911                // if P == U && W == �1� then UNDEFINED;
10912                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10913                    return false;
10914
10915                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10916                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10917                single_regs = true;
10918                add = BitIsSet (opcode, 23);
10919                wback = BitIsSet (opcode, 21);
10920                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10921                n = Bits32 (opcode, 19, 16);
10922
10923                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10924                imm32 = Bits32 (opcode, 7, 0) << 2;
10925                regs = Bits32 (opcode, 7, 0);
10926
10927                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10928                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10929                    return false;
10930
10931                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10932                if ((regs == 0) || ((d + regs) > 32))
10933                    return false;
10934
10935                break;
10936
10937            default:
10938                return false;
10939        }
10940
10941        RegisterInfo base_reg;
10942        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10943
10944        uint32_t Rn = ReadCoreReg (n, &success);
10945        if (!success)
10946            return false;
10947
10948        // address = if add then R[n] else R[n]-imm32;
10949        addr_t address;
10950        if (add)
10951            address = Rn;
10952        else
10953            address = Rn - imm32;
10954
10955        EmulateInstruction::Context context;
10956        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10957        if (wback)
10958        {
10959            uint32_t value;
10960            if (add)
10961                value = Rn + imm32;
10962            else
10963                value = Rn - imm32;
10964
10965            context.type = eContextAdjustBaseRegister;
10966            context.SetRegisterPlusOffset (base_reg, value - Rn);
10967
10968            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10969                return false;
10970        }
10971
10972        const uint32_t addr_byte_size = GetAddressByteSize();
10973        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10974
10975        context.type = eContextRegisterStore;
10976        // for r = 0 to regs-1
10977        for (uint32_t r = 0; r < regs; ++r)
10978        {
10979
10980            if (single_regs)
10981            {
10982                // MemA[address,4] = S[d+r]; address = address+4;
10983                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10984                if (!success)
10985                    return false;
10986
10987                RegisterInfo data_reg;
10988                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10989                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10990                if (!MemAWrite (context, address, data, addr_byte_size))
10991                    return false;
10992
10993                address = address + 4;
10994            }
10995            else
10996            {
10997                // // Store as two word-aligned words in the correct order for current endianness.
10998                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10999                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11000                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11001                if (!success)
11002                    return false;
11003
11004                RegisterInfo data_reg;
11005                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11006
11007                if (GetByteOrder() == eByteOrderBig)
11008                {
11009                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11010                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11011                        return false;
11012
11013                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11014                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11015                        return false;
11016                }
11017                else
11018                {
11019                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11020                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11021                        return false;
11022
11023                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11024                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11025                        return false;
11026                }
11027                // address = address+8;
11028                address = address + 8;
11029            }
11030        }
11031    }
11032    return true;
11033}
11034
11035// A8.6.320
11036// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11037// an optional offset.
11038bool
11039EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11040{
11041#if 0
11042    if ConditionPassed() then
11043        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11044        base = if n == 15 then Align(PC,4) else R[n];
11045        address = if add then (base + imm32) else (base - imm32);
11046        if single_reg then
11047            S[d] = MemA[address,4];
11048        else
11049            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11050            // Combine the word-aligned words in the correct order for current endianness.
11051            D[d] = if BigEndian() then word1:word2 else word2:word1;
11052#endif
11053
11054    bool success = false;
11055
11056    if (ConditionPassed (opcode))
11057    {
11058        bool single_reg;
11059        bool add;
11060        uint32_t imm32;
11061        uint32_t d;
11062        uint32_t n;
11063
11064        switch (encoding)
11065        {
11066            case eEncodingT1:
11067            case eEncodingA1:
11068                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11069                single_reg = false;
11070                add = BitIsSet (opcode, 23);
11071                imm32 = Bits32 (opcode, 7, 0) << 2;
11072
11073                // d = UInt(D:Vd); n = UInt(Rn);
11074                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11075                n = Bits32 (opcode, 19, 16);
11076
11077                break;
11078
11079            case eEncodingT2:
11080            case eEncodingA2:
11081                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11082                single_reg = true;
11083                add = BitIsSet (opcode, 23);
11084                imm32 = Bits32 (opcode, 7, 0) << 2;
11085
11086                // d = UInt(Vd:D); n = UInt(Rn);
11087                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11088                n = Bits32 (opcode, 19, 16);
11089
11090                break;
11091
11092            default:
11093                return false;
11094        }
11095        RegisterInfo base_reg;
11096        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11097
11098        uint32_t Rn = ReadCoreReg (n, &success);
11099        if (!success)
11100            return false;
11101
11102        // base = if n == 15 then Align(PC,4) else R[n];
11103        uint32_t base;
11104        if (n == 15)
11105            base = AlignPC (Rn);
11106        else
11107            base = Rn;
11108
11109        // address = if add then (base + imm32) else (base - imm32);
11110        addr_t address;
11111        if (add)
11112            address = base + imm32;
11113        else
11114            address = base - imm32;
11115
11116        const uint32_t addr_byte_size = GetAddressByteSize();
11117        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11118
11119        EmulateInstruction::Context context;
11120        context.type = eContextRegisterLoad;
11121        context.SetRegisterPlusOffset (base_reg, address - base);
11122
11123        if (single_reg)
11124        {
11125            // S[d] = MemA[address,4];
11126            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11127            if (!success)
11128                return false;
11129
11130            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11131                return false;
11132        }
11133        else
11134        {
11135            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11136            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11137            if (!success)
11138                return false;
11139
11140            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11141            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11142            if (!success)
11143                return false;
11144            // // Combine the word-aligned words in the correct order for current endianness.
11145            // D[d] = if BigEndian() then word1:word2 else word2:word1;
11146            uint64_t data64;
11147            if (GetByteOrder() == eByteOrderBig)
11148            {
11149                data64 = word1;
11150                data64 = (data64 << 32) | word2;
11151            }
11152            else
11153            {
11154                data64 = word2;
11155                data64 = (data64 << 32) | word1;
11156            }
11157
11158            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11159                return false;
11160        }
11161    }
11162    return true;
11163}
11164
11165// A8.6.400 VSTR
11166// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11167// optional offset.
11168bool
11169EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11170{
11171#if 0
11172    if ConditionPassed() then
11173        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11174        address = if add then (R[n] + imm32) else (R[n] - imm32);
11175        if single_reg then
11176            MemA[address,4] = S[d];
11177        else
11178            // Store as two word-aligned words in the correct order for current endianness.
11179            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11180            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11181#endif
11182
11183    bool success = false;
11184
11185    if (ConditionPassed (opcode))
11186    {
11187        bool single_reg;
11188        bool add;
11189        uint32_t imm32;
11190        uint32_t d;
11191        uint32_t n;
11192
11193        switch (encoding)
11194        {
11195            case eEncodingT1:
11196            case eEncodingA1:
11197                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11198                single_reg = false;
11199                add = BitIsSet (opcode, 23);
11200                imm32 = Bits32 (opcode, 7, 0) << 2;
11201
11202                // d = UInt(D:Vd); n = UInt(Rn);
11203                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11204                n = Bits32 (opcode, 19, 16);
11205
11206                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11207                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11208                    return false;
11209
11210                break;
11211
11212            case eEncodingT2:
11213            case eEncodingA2:
11214                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11215                single_reg = true;
11216                add = BitIsSet (opcode, 23);
11217                imm32 = Bits32 (opcode, 7, 0) << 2;
11218
11219                // d = UInt(Vd:D); n = UInt(Rn);
11220                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11221                n = Bits32 (opcode, 19, 16);
11222
11223                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11224                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11225                    return false;
11226
11227                break;
11228
11229            default:
11230                return false;
11231        }
11232
11233        RegisterInfo base_reg;
11234        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11235
11236        uint32_t Rn = ReadCoreReg (n, &success);
11237        if (!success)
11238            return false;
11239
11240        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11241        addr_t address;
11242        if (add)
11243            address = Rn + imm32;
11244        else
11245            address = Rn - imm32;
11246
11247        const uint32_t addr_byte_size = GetAddressByteSize();
11248        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11249
11250        RegisterInfo data_reg;
11251        GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11252        EmulateInstruction::Context context;
11253        context.type = eContextRegisterStore;
11254        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11255
11256        if (single_reg)
11257        {
11258            // MemA[address,4] = S[d];
11259            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11260            if (!success)
11261                return false;
11262
11263            if (!MemAWrite (context, address, data, addr_byte_size))
11264                return false;
11265        }
11266        else
11267        {
11268            // // Store as two word-aligned words in the correct order for current endianness.
11269            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11270            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11271            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11272            if (!success)
11273                return false;
11274
11275            if (GetByteOrder() == eByteOrderBig)
11276            {
11277                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11278                    return false;
11279
11280                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11281                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11282                    return false;
11283            }
11284            else
11285            {
11286                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11287                    return false;
11288
11289                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11290                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11291                    return false;
11292            }
11293        }
11294    }
11295    return true;
11296}
11297
11298// A8.6.307 VLDI1 (multiple single elements)
11299// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11300// element of each register is loaded.
11301bool
11302EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11303{
11304#if 0
11305    if ConditionPassed() then
11306        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11307        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11308        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11309        for r = 0 to regs-1
11310            for e = 0 to elements-1
11311                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11312                address = address + ebytes;
11313#endif
11314
11315    bool success = false;
11316
11317    if (ConditionPassed (opcode))
11318    {
11319        uint32_t regs;
11320        uint32_t alignment;
11321        uint32_t ebytes;
11322        uint32_t esize;
11323        uint32_t elements;
11324        uint32_t d;
11325        uint32_t n;
11326        uint32_t m;
11327        bool wback;
11328        bool register_index;
11329
11330        switch (encoding)
11331        {
11332            case eEncodingT1:
11333            case eEncodingA1:
11334            {
11335                // case type of
11336                    // when �0111�
11337                        // regs = 1; if align<1> == �1� then UNDEFINED;
11338                    // when �1010�
11339                        // regs = 2; if align == �11� then UNDEFINED;
11340                    // when �0110�
11341                        // regs = 3; if align<1> == �1� then UNDEFINED;
11342                    // when �0010�
11343                        // regs = 4;
11344                    // otherwise
11345                        // SEE �Related encodings�;
11346                uint32_t type = Bits32 (opcode, 11, 8);
11347                uint32_t align = Bits32 (opcode, 5, 4);
11348                if (type == 7) // '0111'
11349                {
11350                    regs = 1;
11351                    if (BitIsSet (align, 1))
11352                        return false;
11353                }
11354                else if (type == 10) // '1010'
11355                {
11356                    regs = 2;
11357                    if (align == 3)
11358                        return false;
11359
11360                }
11361                else if (type == 6) // '0110'
11362                {
11363                    regs = 3;
11364                    if (BitIsSet (align, 1))
11365                        return false;
11366                }
11367                else if (type == 2) // '0010'
11368                {
11369                    regs = 4;
11370                }
11371                else
11372                    return false;
11373
11374                // alignment = if align == �00� then 1 else 4 << UInt(align);
11375                if (align == 0)
11376                    alignment = 1;
11377                else
11378                    alignment = 4 << align;
11379
11380                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11381                ebytes = 1 << Bits32 (opcode, 7, 6);
11382                esize = 8 * ebytes;
11383                elements = 8 / ebytes;
11384
11385                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11386                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11387                n = Bits32 (opcode, 19, 15);
11388                m = Bits32 (opcode, 3, 0);
11389
11390                // wback = (m != 15); register_index = (m != 15 && m != 13);
11391                wback = (m != 15);
11392                register_index = ((m != 15) && (m != 13));
11393
11394                // if d+regs > 32 then UNPREDICTABLE;
11395                if ((d + regs) > 32)
11396                    return false;
11397            }
11398                break;
11399
11400            default:
11401                return false;
11402        }
11403
11404        RegisterInfo base_reg;
11405        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11406
11407        uint32_t Rn = ReadCoreReg (n, &success);
11408        if (!success)
11409            return false;
11410
11411        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11412        addr_t address = Rn;
11413        if ((address % alignment) != 0)
11414            return false;
11415
11416        EmulateInstruction::Context context;
11417        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11418        if (wback)
11419        {
11420            uint32_t Rm = ReadCoreReg (m, &success);
11421            if (!success)
11422                return false;
11423
11424            uint32_t offset;
11425            if (register_index)
11426                offset = Rm;
11427            else
11428                offset = 8 * regs;
11429
11430            uint32_t value = Rn + offset;
11431            context.type = eContextAdjustBaseRegister;
11432            context.SetRegisterPlusOffset (base_reg, offset);
11433
11434            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11435                return false;
11436
11437        }
11438
11439        // for r = 0 to regs-1
11440        for (uint32_t r = 0; r < regs; ++r)
11441        {
11442            // for e = 0 to elements-1
11443            uint64_t assembled_data = 0;
11444            for (uint32_t e = 0; e < elements; ++e)
11445            {
11446                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11447                context.type = eContextRegisterLoad;
11448                context.SetRegisterPlusOffset (base_reg, address - Rn);
11449                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11450                if (!success)
11451                    return false;
11452
11453                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11454
11455                // address = address + ebytes;
11456                address = address + ebytes;
11457            }
11458            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11459                return false;
11460        }
11461    }
11462    return true;
11463}
11464
11465// A8.6.308 VLD1 (single element to one lane)
11466//
11467bool
11468EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11469{
11470#if 0
11471    if ConditionPassed() then
11472        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11473        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11474        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11475        Elem[D[d],index,esize] = MemU[address,ebytes];
11476#endif
11477
11478    bool success = false;
11479
11480    if (ConditionPassed (opcode))
11481    {
11482        uint32_t ebytes;
11483        uint32_t esize;
11484        uint32_t index;
11485        uint32_t alignment;
11486        uint32_t d;
11487        uint32_t n;
11488        uint32_t m;
11489        bool wback;
11490        bool register_index;
11491
11492        switch (encoding)
11493        {
11494            case eEncodingT1:
11495            case eEncodingA1:
11496            {
11497                uint32_t size = Bits32 (opcode, 11, 10);
11498                uint32_t index_align = Bits32 (opcode, 7, 4);
11499                // if size == �11� then SEE VLD1 (single element to all lanes);
11500                if (size == 3)
11501                   return EmulateVLD1SingleAll (opcode, encoding);
11502                // case size of
11503                if (size == 0) // when '00'
11504                {
11505                    // if index_align<0> != �0� then UNDEFINED;
11506                    if (BitIsClear (index_align, 0))
11507                        return false;
11508
11509                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11510                    ebytes = 1;
11511                    esize = 8;
11512                    index = Bits32 (index_align, 3, 1);
11513                    alignment = 1;
11514                }
11515                else if (size == 1) // when �01�
11516                {
11517                    // if index_align<1> != �0� then UNDEFINED;
11518                    if (BitIsClear (index_align, 1))
11519                        return false;
11520
11521                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11522                    ebytes = 2;
11523                    esize = 16;
11524                    index = Bits32 (index_align, 3, 2);
11525
11526                    // alignment = if index_align<0> == �0� then 1 else 2;
11527                    if (BitIsClear (index_align, 0))
11528                        alignment = 1;
11529                    else
11530                        alignment = 2;
11531                }
11532                else if (size == 2) // when �10�
11533                {
11534                    // if index_align<2> != �0� then UNDEFINED;
11535                    if (BitIsClear (index_align, 2))
11536                        return false;
11537
11538                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11539                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11540                        return false;
11541
11542                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11543                    ebytes = 4;
11544                    esize = 32;
11545                    index = Bit32 (index_align, 3);
11546
11547                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11548                    if (Bits32 (index_align, 1, 0) == 0)
11549                        alignment = 1;
11550                    else
11551                        alignment = 4;
11552                }
11553                else
11554                {
11555                    return false;
11556                }
11557                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11558                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11559                n = Bits32 (opcode, 19, 16);
11560                m = Bits32 (opcode, 3, 0);
11561
11562                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11563                wback = (m != 15);
11564                register_index = ((m != 15) && (m != 13));
11565
11566                if (n == 15)
11567                    return false;
11568
11569            }
11570                break;
11571
11572            default:
11573                return false;
11574        }
11575
11576        RegisterInfo base_reg;
11577        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11578
11579        uint32_t Rn = ReadCoreReg (n, &success);
11580        if (!success)
11581            return false;
11582
11583        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11584        addr_t address = Rn;
11585        if ((address % alignment) != 0)
11586            return false;
11587
11588        EmulateInstruction::Context context;
11589        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11590        if (wback)
11591        {
11592            uint32_t Rm = ReadCoreReg (m, &success);
11593            if (!success)
11594                return false;
11595
11596            uint32_t offset;
11597            if (register_index)
11598                offset = Rm;
11599            else
11600                offset = ebytes;
11601
11602            uint32_t value = Rn + offset;
11603
11604            context.type = eContextAdjustBaseRegister;
11605            context.SetRegisterPlusOffset (base_reg, offset);
11606
11607            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11608                return false;
11609        }
11610
11611        // Elem[D[d],index,esize] = MemU[address,ebytes];
11612        uint32_t element = MemURead (context, address, esize, 0, &success);
11613        if (!success)
11614            return false;
11615
11616        element = element << (index * esize);
11617
11618        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11619        if (!success)
11620            return false;
11621
11622        uint64_t all_ones = -1;
11623        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11624                                                          // at element & to the right of element.
11625        if (index > 0)
11626            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11627                                                                     // now mask should be 0's where element goes & 1's
11628                                                                     // everywhere else.
11629
11630        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11631        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11632
11633        context.type = eContextRegisterLoad;
11634        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11635            return false;
11636    }
11637    return true;
11638}
11639
11640// A8.6.391 VST1 (multiple single elements)
11641// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11642// interleaving.  Every element of each register is stored.
11643bool
11644EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11645{
11646#if 0
11647    if ConditionPassed() then
11648        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11649        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11650        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11651        for r = 0 to regs-1
11652            for e = 0 to elements-1
11653                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11654                address = address + ebytes;
11655#endif
11656
11657    bool success = false;
11658
11659    if (ConditionPassed (opcode))
11660    {
11661        uint32_t regs;
11662        uint32_t alignment;
11663        uint32_t ebytes;
11664        uint32_t esize;
11665        uint32_t elements;
11666        uint32_t d;
11667        uint32_t n;
11668        uint32_t m;
11669        bool wback;
11670        bool register_index;
11671
11672        switch (encoding)
11673        {
11674            case eEncodingT1:
11675            case eEncodingA1:
11676            {
11677                uint32_t type = Bits32 (opcode, 11, 8);
11678                uint32_t align = Bits32 (opcode, 5, 4);
11679
11680                // case type of
11681                if (type == 7)    // when �0111�
11682                {
11683                    // regs = 1; if align<1> == �1� then UNDEFINED;
11684                    regs = 1;
11685                    if (BitIsSet (align, 1))
11686                        return false;
11687                }
11688                else if (type == 10) // when �1010�
11689                {
11690                    // regs = 2; if align == �11� then UNDEFINED;
11691                    regs = 2;
11692                    if (align == 3)
11693                        return false;
11694                }
11695                else if (type == 6) // when �0110�
11696                {
11697                    // regs = 3; if align<1> == �1� then UNDEFINED;
11698                    regs = 3;
11699                    if (BitIsSet (align, 1))
11700                        return false;
11701                }
11702                else if (type == 2) // when �0010�
11703                    // regs = 4;
11704                    regs = 4;
11705                else // otherwise
11706                    // SEE �Related encodings�;
11707                    return false;
11708
11709                // alignment = if align == �00� then 1 else 4 << UInt(align);
11710                if (align == 0)
11711                    alignment = 1;
11712                else
11713                    alignment = 4 << align;
11714
11715                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11716                ebytes = 1 << Bits32 (opcode,7, 6);
11717                esize = 8 * ebytes;
11718                elements = 8 / ebytes;
11719
11720                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11721                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11722                n = Bits32 (opcode, 19, 16);
11723                m = Bits32 (opcode, 3, 0);
11724
11725                // wback = (m != 15); register_index = (m != 15 && m != 13);
11726                wback = (m != 15);
11727                register_index = ((m != 15) && (m != 13));
11728
11729                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11730                if ((d + regs) > 32)
11731                    return false;
11732
11733                if (n == 15)
11734                    return false;
11735
11736            }
11737                break;
11738
11739            default:
11740                return false;
11741        }
11742
11743        RegisterInfo base_reg;
11744        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11745
11746        uint32_t Rn = ReadCoreReg (n, &success);
11747        if (!success)
11748            return false;
11749
11750        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11751        addr_t address = Rn;
11752        if ((address % alignment) != 0)
11753            return false;
11754
11755        EmulateInstruction::Context context;
11756        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11757        if (wback)
11758        {
11759            uint32_t Rm = ReadCoreReg (m, &success);
11760            if (!success)
11761                return false;
11762
11763            uint32_t offset;
11764            if (register_index)
11765                offset = Rm;
11766            else
11767                offset = 8 * regs;
11768
11769            context.type = eContextAdjustBaseRegister;
11770            context.SetRegisterPlusOffset (base_reg, offset);
11771
11772            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11773                return false;
11774        }
11775
11776        RegisterInfo data_reg;
11777        context.type = eContextRegisterStore;
11778        // for r = 0 to regs-1
11779        for (uint32_t r = 0; r < regs; ++r)
11780        {
11781            GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11782            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11783            if (!success)
11784                return false;
11785
11786             // for e = 0 to elements-1
11787            for (uint32_t e = 0; e < elements; ++e)
11788            {
11789                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11790                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11791
11792                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11793                if (!MemUWrite (context, address, word, ebytes))
11794                    return false;
11795
11796                // address = address + ebytes;
11797                address = address + ebytes;
11798            }
11799        }
11800    }
11801    return true;
11802}
11803
11804// A8.6.392 VST1 (single element from one lane)
11805// This instruction stores one element to memory from one element of a register.
11806bool
11807EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11808{
11809#if 0
11810    if ConditionPassed() then
11811        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11812        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11813        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11814        MemU[address,ebytes] = Elem[D[d],index,esize];
11815#endif
11816
11817    bool success = false;
11818
11819    if (ConditionPassed (opcode))
11820    {
11821        uint32_t ebytes;
11822        uint32_t esize;
11823        uint32_t index;
11824        uint32_t alignment;
11825        uint32_t d;
11826        uint32_t n;
11827        uint32_t m;
11828        bool wback;
11829        bool register_index;
11830
11831        switch (encoding)
11832        {
11833            case eEncodingT1:
11834            case eEncodingA1:
11835            {
11836                uint32_t size = Bits32 (opcode, 11, 10);
11837                uint32_t index_align = Bits32 (opcode, 7, 4);
11838
11839                // if size == �11� then UNDEFINED;
11840                if (size == 3)
11841                    return false;
11842
11843                // case size of
11844                if (size == 0) // when �00�
11845                {
11846                    // if index_align<0> != �0� then UNDEFINED;
11847                    if (BitIsClear (index_align, 0))
11848                        return false;
11849                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11850                    ebytes = 1;
11851                    esize = 8;
11852                    index = Bits32 (index_align, 3, 1);
11853                    alignment = 1;
11854                }
11855                else if (size == 1) // when �01�
11856                {
11857                    // if index_align<1> != �0� then UNDEFINED;
11858                    if (BitIsClear (index_align, 1))
11859                        return false;
11860
11861                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11862                    ebytes = 2;
11863                    esize = 16;
11864                    index = Bits32 (index_align, 3, 2);
11865
11866                    // alignment = if index_align<0> == �0� then 1 else 2;
11867                    if (BitIsClear (index_align, 0))
11868                        alignment = 1;
11869                    else
11870                        alignment = 2;
11871                }
11872                else if (size == 2) // when �10�
11873                {
11874                    // if index_align<2> != �0� then UNDEFINED;
11875                    if (BitIsClear (index_align, 2))
11876                        return false;
11877
11878                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11879                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11880                        return false;
11881
11882                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11883                    ebytes = 4;
11884                    esize = 32;
11885                    index = Bit32 (index_align, 3);
11886
11887                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11888                    if (Bits32 (index_align, 1, 0) == 0)
11889                        alignment = 1;
11890                    else
11891                        alignment = 4;
11892                }
11893                else
11894                {
11895                    return false;
11896                }
11897                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11898                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11899                n = Bits32 (opcode, 19, 16);
11900                m = Bits32 (opcode, 3, 0);
11901
11902                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11903                wback = (m != 15);
11904                register_index = ((m != 15) && (m != 13));
11905
11906                if (n == 15)
11907                    return false;
11908            }
11909                break;
11910
11911            default:
11912                return false;
11913        }
11914
11915        RegisterInfo base_reg;
11916        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11917
11918        uint32_t Rn = ReadCoreReg (n, &success);
11919        if (!success)
11920            return false;
11921
11922        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11923        addr_t address = Rn;
11924        if ((address % alignment) != 0)
11925            return false;
11926
11927        EmulateInstruction::Context context;
11928        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11929        if (wback)
11930        {
11931            uint32_t Rm = ReadCoreReg (m, &success);
11932            if (!success)
11933                return false;
11934
11935            uint32_t offset;
11936            if (register_index)
11937                offset = Rm;
11938            else
11939                offset = ebytes;
11940
11941            context.type = eContextAdjustBaseRegister;
11942            context.SetRegisterPlusOffset (base_reg, offset);
11943
11944            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11945                return false;
11946        }
11947
11948        // MemU[address,ebytes] = Elem[D[d],index,esize];
11949        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11950        if (!success)
11951            return false;
11952
11953        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11954
11955        RegisterInfo data_reg;
11956        GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11957        context.type = eContextRegisterStore;
11958        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11959
11960        if (!MemUWrite (context, address, word, ebytes))
11961            return false;
11962    }
11963    return true;
11964}
11965
11966// A8.6.309 VLD1 (single element to all lanes)
11967// This instruction loads one element from memory into every element of one or two vectors.
11968bool
11969EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11970{
11971#if 0
11972    if ConditionPassed() then
11973        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11974        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11975        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11976        replicated_element = Replicate(MemU[address,ebytes], elements);
11977        for r = 0 to regs-1
11978            D[d+r] = replicated_element;
11979#endif
11980
11981    bool success = false;
11982
11983    if (ConditionPassed (opcode))
11984    {
11985        uint32_t ebytes;
11986        uint32_t elements;
11987        uint32_t regs;
11988        uint32_t alignment;
11989        uint32_t d;
11990        uint32_t n;
11991        uint32_t m;
11992        bool wback;
11993        bool register_index;
11994
11995        switch (encoding)
11996        {
11997            case eEncodingT1:
11998            case eEncodingA1:
11999            {
12000                //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
12001                uint32_t size = Bits32 (opcode, 7, 6);
12002                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12003                    return false;
12004
12005                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
12006                ebytes = 1 << size;
12007                elements = 8 / ebytes;
12008                if (BitIsClear (opcode, 5))
12009                    regs = 1;
12010                else
12011                    regs = 2;
12012
12013                //alignment = if a == �0� then 1 else ebytes;
12014                if (BitIsClear (opcode, 4))
12015                    alignment = 1;
12016                else
12017                    alignment = ebytes;
12018
12019                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12020                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12021                n = Bits32 (opcode, 19, 16);
12022                m = Bits32 (opcode, 3, 0);
12023
12024                //wback = (m != 15); register_index = (m != 15 && m != 13);
12025                wback = (m != 15);
12026                register_index = ((m != 15) && (m != 13));
12027
12028                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12029                if ((d + regs) > 32)
12030                    return false;
12031
12032                if (n == 15)
12033                    return false;
12034            }
12035            break;
12036
12037            default:
12038                return false;
12039        }
12040
12041        RegisterInfo base_reg;
12042        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12043
12044        uint32_t Rn = ReadCoreReg (n, &success);
12045        if (!success)
12046            return false;
12047
12048        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12049        addr_t address = Rn;
12050        if ((address % alignment) != 0)
12051            return false;
12052
12053        EmulateInstruction::Context context;
12054        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12055        if (wback)
12056        {
12057            uint32_t Rm = ReadCoreReg (m, &success);
12058            if (!success)
12059                return false;
12060
12061            uint32_t offset;
12062            if (register_index)
12063                offset = Rm;
12064            else
12065                offset = ebytes;
12066
12067            context.type = eContextAdjustBaseRegister;
12068            context.SetRegisterPlusOffset (base_reg, offset);
12069
12070            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12071                return false;
12072        }
12073
12074        // replicated_element = Replicate(MemU[address,ebytes], elements);
12075
12076        context.type = eContextRegisterLoad;
12077        uint64_t word = MemURead (context, address, ebytes, 0, &success);
12078        if (!success)
12079            return false;
12080
12081        uint64_t replicated_element = 0;
12082        uint32_t esize = ebytes * 8;
12083        for (uint32_t e = 0; e < elements; ++e)
12084            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12085
12086        // for r = 0 to regs-1
12087        for (uint32_t r = 0; r < regs; ++r)
12088        {
12089            // D[d+r] = replicated_element;
12090            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12091                return false;
12092        }
12093    }
12094    return true;
12095}
12096
12097// B6.2.13 SUBS PC, LR and related instructions
12098//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12099// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12100bool
12101EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12102{
12103#if 0
12104    if ConditionPassed() then
12105        EncodingSpecificOperations();
12106        if CurrentInstrSet() == InstrSet_ThumbEE then
12107            UNPREDICTABLE;
12108        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12109        case opcode of
12110            when �0000� result = R[n] AND operand2; // AND
12111            when �0001result = R[n] EOR operand2; // EOR
12112            when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12113            when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12114            when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12115            when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12116            when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12117            when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12118            when1100result = R[n] OR operand2; // ORR
12119            when1101result = operand2; // MOV
12120            when1110result = R[n] AND NOT(operand2); // BIC
12121            when1111result = NOT(operand2); // MVN
12122        CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12123        BranchWritePC(result);
12124#endif
12125
12126    bool success = false;
12127
12128    if (ConditionPassed (opcode))
12129    {
12130        uint32_t n;
12131        uint32_t m;
12132        uint32_t imm32;
12133        bool register_form;
12134        ARM_ShifterType shift_t;
12135        uint32_t shift_n;
12136        uint32_t code;
12137
12138        switch (encoding)
12139        {
12140            case eEncodingT1:
12141                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12142                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12143                n = 14;
12144                imm32 = Bits32 (opcode, 7, 0);
12145                register_form = false;
12146                code = 2;
12147
12148                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12149                if (InITBlock() && !LastInITBlock())
12150                    return false;
12151
12152                break;
12153
12154            case eEncodingA1:
12155                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12156                n = Bits32 (opcode, 19, 16);
12157                imm32 = ARMExpandImm (opcode);
12158                register_form = false;
12159                code = Bits32 (opcode, 24, 21);
12160
12161                break;
12162
12163            case eEncodingA2:
12164                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12165                n = Bits32 (opcode, 19, 16);
12166                m = Bits32 (opcode, 3, 0);
12167                register_form = true;
12168
12169                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12170                shift_n = DecodeImmShiftARM (opcode, shift_t);
12171
12172                break;
12173
12174            default:
12175                return false;
12176        }
12177
12178        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12179        uint32_t operand2;
12180        if (register_form)
12181        {
12182            uint32_t Rm = ReadCoreReg (m, &success);
12183            if (!success)
12184                return false;
12185
12186            operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12187            if (!success)
12188                return false;
12189        }
12190        else
12191        {
12192            operand2 = imm32;
12193        }
12194
12195        uint32_t Rn = ReadCoreReg (n, &success);
12196        if (!success)
12197            return false;
12198
12199        AddWithCarryResult result;
12200
12201        // case opcode of
12202        switch (code)
12203        {
12204            case 0: // when �0000�
12205                // result = R[n] AND operand2; // AND
12206                result.result = Rn & operand2;
12207                break;
12208
12209            case 1: // when �0001�
12210                // result = R[n] EOR operand2; // EOR
12211                result.result = Rn ^ operand2;
12212                break;
12213
12214            case 2: // when �0010�
12215                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12216                result = AddWithCarry (Rn, ~(operand2), 1);
12217                break;
12218
12219            case 3: // when �0011�
12220                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12221                result = AddWithCarry (~(Rn), operand2, 1);
12222                break;
12223
12224            case 4: // when �0100�
12225                // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12226                result = AddWithCarry (Rn, operand2, 0);
12227                break;
12228
12229            case 5: // when �0101�
12230                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12231                result = AddWithCarry (Rn, operand2, APSR_C);
12232                break;
12233
12234            case 6: // when �0110�
12235                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12236                result = AddWithCarry (Rn, ~(operand2), APSR_C);
12237                break;
12238
12239            case 7: // when �0111�
12240                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12241                result = AddWithCarry (~(Rn), operand2, APSR_C);
12242                break;
12243
12244            case 10: // when �1100�
12245                // result = R[n] OR operand2; // ORR
12246                result.result = Rn | operand2;
12247                break;
12248
12249            case 11: // when �1101�
12250                // result = operand2; // MOV
12251                result.result = operand2;
12252                break;
12253
12254            case 12: // when �1110�
12255                // result = R[n] AND NOT(operand2); // BIC
12256                result.result = Rn & ~(operand2);
12257                break;
12258
12259            case 15: // when �1111�
12260                // result = NOT(operand2); // MVN
12261                result.result = ~(operand2);
12262                break;
12263
12264            default:
12265                return false;
12266        }
12267        // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12268
12269        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12270        // the best.
12271        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12272        if (!success)
12273            return false;
12274
12275        CPSRWriteByInstr (spsr, 15, true);
12276
12277        // BranchWritePC(result);
12278        EmulateInstruction::Context context;
12279        context.type = eContextAdjustPC;
12280        context.SetImmediate (result.result);
12281
12282        BranchWritePC (context, result.result);
12283    }
12284    return true;
12285}
12286
12287EmulateInstructionARM::ARMOpcode*
12288EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12289{
12290    static ARMOpcode
12291    g_arm_opcodes[] =
12292    {
12293        //----------------------------------------------------------------------
12294        // Prologue instructions
12295        //----------------------------------------------------------------------
12296
12297        // push register(s)
12298        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12299        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12300
12301        // set r7 to point to a stack offset
12302        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12303        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12304        // copy the stack pointer to ip
12305        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12306        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12307        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12308
12309        // adjust the stack pointer
12310        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12311        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12312
12313        // push one register
12314        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12315        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12316
12317        // vector push consecutive extension register(s)
12318        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12319        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12320
12321        //----------------------------------------------------------------------
12322        // Epilogue instructions
12323        //----------------------------------------------------------------------
12324
12325        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12326        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12327        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12328        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12329
12330        //----------------------------------------------------------------------
12331        // Supervisor Call (previously Software Interrupt)
12332        //----------------------------------------------------------------------
12333        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12334
12335        //----------------------------------------------------------------------
12336        // Branch instructions
12337        //----------------------------------------------------------------------
12338        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12339        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12340        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12341        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12342        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12343        // for example, "bx lr"
12344        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12345        // bxj
12346        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12347
12348        //----------------------------------------------------------------------
12349        // Data-processing instructions
12350        //----------------------------------------------------------------------
12351        // adc (immediate)
12352        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12353        // adc (register)
12354        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12355        // add (immediate)
12356        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12357        // add (register)
12358        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12359        // add (register-shifted register)
12360        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12361        // adr
12362        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12363        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12364        // and (immediate)
12365        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12366        // and (register)
12367        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12368        // bic (immediate)
12369        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12370        // bic (register)
12371        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12372        // eor (immediate)
12373        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12374        // eor (register)
12375        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12376        // orr (immediate)
12377        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12378        // orr (register)
12379        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12380        // rsb (immediate)
12381        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12382        // rsb (register)
12383        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12384        // rsc (immediate)
12385        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12386        // rsc (register)
12387        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12388        // sbc (immediate)
12389        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12390        // sbc (register)
12391        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12392        // sub (immediate, ARM)
12393        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12394        // sub (sp minus immediate)
12395        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12396        // sub (register)
12397        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12398        // teq (immediate)
12399        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12400        // teq (register)
12401        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12402        // tst (immediate)
12403        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12404        // tst (register)
12405        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12406
12407        // mov (immediate)
12408        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12409        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12410        // mov (register)
12411        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12412        // mvn (immediate)
12413        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12414        // mvn (register)
12415        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12416        // cmn (immediate)
12417        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12418        // cmn (register)
12419        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12420        // cmp (immediate)
12421        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12422        // cmp (register)
12423        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12424        // asr (immediate)
12425        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12426        // asr (register)
12427        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12428        // lsl (immediate)
12429        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12430        // lsl (register)
12431        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12432        // lsr (immediate)
12433        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12434        // lsr (register)
12435        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12436        // rrx is a special case encoding of ror (immediate)
12437        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12438        // ror (immediate)
12439        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12440        // ror (register)
12441        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12442        // mul
12443        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12444
12445        // subs pc, lr and related instructions
12446        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12447        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12448
12449        //----------------------------------------------------------------------
12450        // Load instructions
12451        //----------------------------------------------------------------------
12452        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12453        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12454        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12455        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12456        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12457        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12458        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12459        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12460        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12461        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12462        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12463        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12464        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12465        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12466        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12467        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12468        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12469        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12470        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12471        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12472        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12473        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12474        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12475        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12476        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12477
12478        //----------------------------------------------------------------------
12479        // Store instructions
12480        //----------------------------------------------------------------------
12481        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12482        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12483        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12484        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12485        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12486        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12487        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12488        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12489        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12490        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12491        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12492        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12493        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12494        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12495        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12496        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12497        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12498
12499        //----------------------------------------------------------------------
12500        // Other instructions
12501        //----------------------------------------------------------------------
12502        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12503        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12504        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12505        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12506        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12507
12508    };
12509    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12510
12511    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12512    {
12513        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12514            (g_arm_opcodes[i].variants & arm_isa) != 0)
12515            return &g_arm_opcodes[i];
12516    }
12517    return NULL;
12518}
12519
12520
12521EmulateInstructionARM::ARMOpcode*
12522EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12523{
12524
12525    static ARMOpcode
12526    g_thumb_opcodes[] =
12527    {
12528        //----------------------------------------------------------------------
12529        // Prologue instructions
12530        //----------------------------------------------------------------------
12531
12532        // push register(s)
12533        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12534        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12535        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12536
12537        // set r7 to point to a stack offset
12538        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12539        // copy the stack pointer to r7
12540        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12541        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12542        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12543
12544        // PC-relative load into register (see also EmulateADDSPRm)
12545        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12546
12547        // adjust the stack pointer
12548        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12549        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12550        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12551        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12552        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12553
12554        // vector push consecutive extension register(s)
12555        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12556        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12557
12558        //----------------------------------------------------------------------
12559        // Epilogue instructions
12560        //----------------------------------------------------------------------
12561
12562        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12563        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12564        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12565        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12566        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12567        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12568        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12569
12570        //----------------------------------------------------------------------
12571        // Supervisor Call (previously Software Interrupt)
12572        //----------------------------------------------------------------------
12573        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12574
12575        //----------------------------------------------------------------------
12576        // If Then makes up to four following instructions conditional.
12577        //----------------------------------------------------------------------
12578        // The next 5 opcode _must_ come before the if then instruction
12579        { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12580        { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12581        { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12582        { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12583        { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12584        { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12585
12586        //----------------------------------------------------------------------
12587        // Branch instructions
12588        //----------------------------------------------------------------------
12589        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12590        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12591        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12592        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12593        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12594        // J1 == J2 == 1
12595        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12596        // J1 == J2 == 1
12597        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12598        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12599        // for example, "bx lr"
12600        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12601        // bxj
12602        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12603        // compare and branch
12604        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12605        // table branch byte
12606        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12607        // table branch halfword
12608        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12609
12610        //----------------------------------------------------------------------
12611        // Data-processing instructions
12612        //----------------------------------------------------------------------
12613        // adc (immediate)
12614        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12615        // adc (register)
12616        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12617        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12618        // add (register)
12619        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12620        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12621        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12622        // adr
12623        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12624        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12625        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12626        // and (immediate)
12627        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12628        // and (register)
12629        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12630        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12631        // bic (immediate)
12632        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12633        // bic (register)
12634        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12635        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12636        // eor (immediate)
12637        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12638        // eor (register)
12639        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12640        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12641        // orr (immediate)
12642        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12643        // orr (register)
12644        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12645        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12646        // rsb (immediate)
12647        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12648        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12649        // rsb (register)
12650        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12651        // sbc (immediate)
12652        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12653        // sbc (register)
12654        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12655        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12656        // add (immediate, Thumb)
12657        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12658        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12659        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12660        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12661        // sub (immediate, Thumb)
12662        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12663        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12664        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12665        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12666        // sub (sp minus immediate)
12667        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12668        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12669        // sub (register)
12670        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12671        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12672        // teq (immediate)
12673        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12674        // teq (register)
12675        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12676        // tst (immediate)
12677        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12678        // tst (register)
12679        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12680        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12681
12682
12683        // move from high register to high register
12684        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12685        // move from low register to low register
12686        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12687        // mov{s}<c>.w <Rd>, <Rm>
12688        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12689        // move immediate
12690        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12691        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12692        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12693        // mvn (immediate)
12694        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12695        // mvn (register)
12696        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12697        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12698        // cmn (immediate)
12699        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12700        // cmn (register)
12701        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12702        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12703        // cmp (immediate)
12704        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12705        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12706        // cmp (register) (Rn and Rm both from r0-r7)
12707        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12708        // cmp (register) (Rn and Rm not both from r0-r7)
12709        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12710        // asr (immediate)
12711        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12712        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12713        // asr (register)
12714        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12715        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12716        // lsl (immediate)
12717        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12718        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12719        // lsl (register)
12720        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12721        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12722        // lsr (immediate)
12723        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12724        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12725        // lsr (register)
12726        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12727        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12728        // rrx is a special case encoding of ror (immediate)
12729        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12730        // ror (immediate)
12731        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12732        // ror (register)
12733        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12734        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12735        // mul
12736        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12737        // mul
12738        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12739
12740        // subs pc, lr and related instructions
12741        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12742
12743        //----------------------------------------------------------------------
12744        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12745        // otherwise the wrong instructions will be selected.
12746        //----------------------------------------------------------------------
12747
12748        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12749        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12750
12751        //----------------------------------------------------------------------
12752        // Load instructions
12753        //----------------------------------------------------------------------
12754        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12755        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12756        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12757        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12758        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12759        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12760        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12761                  // Thumb2 PC-relative load into register
12762        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12763        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12764        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12765        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12766        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12767        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12768        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12769        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12770        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12771        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12772        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12773        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12774        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12775        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12776        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12777        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12778        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12779        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12780        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12781        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12782        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12783        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12784        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12785        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12786        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12787        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12788        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12789        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12790        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12791        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12792        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12793        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12794        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12795
12796        //----------------------------------------------------------------------
12797        // Store instructions
12798        //----------------------------------------------------------------------
12799        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12800        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12801        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12802        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12803        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12804        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12805        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12806        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12807        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12808        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12809        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12810        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12811        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12812        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12813        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12814        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12815        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12816        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12817        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12818        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12819        { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12820        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12821
12822        //----------------------------------------------------------------------
12823        // Other instructions
12824        //----------------------------------------------------------------------
12825        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12826        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12827        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12828        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12829        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12830        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12831        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12832        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12833    };
12834
12835    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12836    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12837    {
12838        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12839            (g_thumb_opcodes[i].variants & arm_isa) != 0)
12840            return &g_thumb_opcodes[i];
12841    }
12842    return NULL;
12843}
12844
12845bool
12846EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12847{
12848    m_arch = arch;
12849    m_arm_isa = 0;
12850    const char *arch_cstr = arch.GetArchitectureName ();
12851    if (arch_cstr)
12852    {
12853        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12854        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12855        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12856        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12857        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12858        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12859        else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12860        else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12861        else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12862        else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12863        else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12864        else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12865        else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12866    }
12867    return m_arm_isa != 0;
12868}
12869
12870bool
12871EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12872{
12873    if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12874    {
12875        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12876            m_opcode_mode = eModeThumb;
12877        else
12878        {
12879            AddressClass addr_class = inst_addr.GetAddressClass();
12880
12881            if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12882                m_opcode_mode = eModeARM;
12883            else if (addr_class == eAddressClassCodeAlternateISA)
12884                m_opcode_mode = eModeThumb;
12885            else
12886                return false;
12887        }
12888        if (m_opcode_mode == eModeThumb)
12889            m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12890        else
12891            m_opcode_cpsr = CPSR_MODE_USR;
12892        return true;
12893    }
12894    return false;
12895}
12896
12897bool
12898EmulateInstructionARM::ReadInstruction ()
12899{
12900    bool success = false;
12901    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12902    if (success)
12903    {
12904        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12905        if (success)
12906        {
12907            Context read_inst_context;
12908            read_inst_context.type = eContextReadOpcode;
12909            read_inst_context.SetNoArgs ();
12910
12911            if (m_opcode_cpsr & MASK_CPSR_T)
12912            {
12913                m_opcode_mode = eModeThumb;
12914                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12915
12916                if (success)
12917                {
12918                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12919                    {
12920                        m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
12921                    }
12922                    else
12923                    {
12924                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
12925                    }
12926                }
12927            }
12928            else
12929            {
12930                m_opcode_mode = eModeARM;
12931                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
12932            }
12933        }
12934    }
12935    if (!success)
12936    {
12937        m_opcode_mode = eModeInvalid;
12938        m_addr = LLDB_INVALID_ADDRESS;
12939    }
12940    return success;
12941}
12942
12943uint32_t
12944EmulateInstructionARM::ArchVersion ()
12945{
12946    return m_arm_isa;
12947}
12948
12949bool
12950EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12951{
12952   // If we are ignoring conditions, then always return true.
12953   // this allows us to iterate over disassembly code and still
12954   // emulate an instruction even if we don't have all the right
12955   // bits set in the CPSR register...
12956    if (m_ignore_conditions)
12957        return true;
12958
12959    if (is_conditional)
12960        *is_conditional = true;
12961
12962    const uint32_t cond = CurrentCond (opcode);
12963
12964    if (cond == UINT32_MAX)
12965        return false;
12966
12967    bool result = false;
12968    switch (UnsignedBits(cond, 3, 1))
12969    {
12970    case 0:
12971		if (m_opcode_cpsr == 0)
12972			result = true;
12973        else
12974            result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12975		break;
12976    case 1:
12977        if (m_opcode_cpsr == 0)
12978            result = true;
12979        else
12980            result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12981		break;
12982    case 2:
12983        if (m_opcode_cpsr == 0)
12984            result = true;
12985        else
12986            result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12987		break;
12988    case 3:
12989        if (m_opcode_cpsr == 0)
12990            result = true;
12991        else
12992            result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12993		break;
12994    case 4:
12995        if (m_opcode_cpsr == 0)
12996            result = true;
12997        else
12998            result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12999		break;
13000    case 5:
13001        if (m_opcode_cpsr == 0)
13002            result = true;
13003        else
13004		{
13005            bool n = (m_opcode_cpsr & MASK_CPSR_N);
13006            bool v = (m_opcode_cpsr & MASK_CPSR_V);
13007            result = n == v;
13008        }
13009        break;
13010    case 6:
13011        if (m_opcode_cpsr == 0)
13012            result = true;
13013        else
13014		{
13015            bool n = (m_opcode_cpsr & MASK_CPSR_N);
13016            bool v = (m_opcode_cpsr & MASK_CPSR_V);
13017            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13018        }
13019        break;
13020    case 7:
13021        // Always execute (cond == 0b1110, or the special 0b1111 which gives
13022        // opcodes different meanings, but always means execution happpens.
13023        if (is_conditional)
13024            *is_conditional = false;
13025        result = true;
13026        break;
13027    }
13028
13029    if (cond & 1)
13030        result = !result;
13031    return result;
13032}
13033
13034uint32_t
13035EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13036{
13037    switch (m_opcode_mode)
13038    {
13039    case eModeInvalid:
13040        break;
13041
13042    case eModeARM:
13043        return UnsignedBits(opcode, 31, 28);
13044
13045    case eModeThumb:
13046        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13047        // 'cond' field of the encoding.
13048        {
13049            const uint32_t byte_size = m_opcode.GetByteSize();
13050            if (byte_size == 2)
13051            {
13052                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13053                    return Bits32(opcode, 11, 7);
13054            }
13055            else if (byte_size == 4)
13056            {
13057                if (Bits32(opcode, 31, 27) == 0x1e &&
13058                    Bits32(opcode, 15, 14) == 0x02 &&
13059                    Bits32(opcode, 12, 12) == 0x00 &&
13060                    Bits32(opcode, 25, 22) <= 0x0d)
13061                {
13062                    return Bits32(opcode, 25, 22);
13063                }
13064            }
13065            else
13066                // We have an invalid thumb instruction, let's bail out.
13067                break;
13068
13069            return m_it_session.GetCond();
13070        }
13071    }
13072    return UINT32_MAX;  // Return invalid value
13073}
13074
13075bool
13076EmulateInstructionARM::InITBlock()
13077{
13078    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13079}
13080
13081bool
13082EmulateInstructionARM::LastInITBlock()
13083{
13084    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13085}
13086
13087bool
13088EmulateInstructionARM::BadMode (uint32_t mode)
13089{
13090
13091    switch (mode)
13092    {
13093        case 16: return false; // '10000'
13094        case 17: return false; // '10001'
13095        case 18: return false; // '10010'
13096        case 19: return false; // '10011'
13097        case 22: return false; // '10110'
13098        case 23: return false; // '10111'
13099        case 27: return false; // '11011'
13100        case 31: return false; // '11111'
13101        default: return true;
13102    }
13103    return true;
13104}
13105
13106bool
13107EmulateInstructionARM::CurrentModeIsPrivileged ()
13108{
13109    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13110
13111    if (BadMode (mode))
13112        return false;
13113
13114    if (mode == 16)
13115        return false;
13116
13117    return true;
13118}
13119
13120void
13121EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13122{
13123    bool privileged = CurrentModeIsPrivileged();
13124
13125    uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13126
13127    if (BitIsSet (bytemask, 3))
13128    {
13129        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13130        if (affect_execstate)
13131            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13132    }
13133
13134    if (BitIsSet (bytemask, 2))
13135    {
13136        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13137    }
13138
13139    if (BitIsSet (bytemask, 1))
13140    {
13141        if (affect_execstate)
13142            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13143        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13144        if (privileged)
13145            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13146    }
13147
13148    if (BitIsSet (bytemask, 0))
13149    {
13150        if (privileged)
13151            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13152        if (affect_execstate)
13153            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13154        if (privileged)
13155            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13156    }
13157
13158    m_opcode_cpsr = tmp_cpsr;
13159}
13160
13161
13162bool
13163EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13164{
13165    addr_t target;
13166
13167    // Check the current instruction set.
13168    if (CurrentInstrSet() == eModeARM)
13169        target = addr & 0xfffffffc;
13170    else
13171        target = addr & 0xfffffffe;
13172
13173    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13174        return false;
13175
13176    return true;
13177}
13178
13179// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13180bool
13181EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13182{
13183    addr_t target;
13184    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13185    // we want to record it and issue a WriteRegister callback so the clients
13186    // can track the mode changes accordingly.
13187    bool cpsr_changed = false;
13188
13189    if (BitIsSet(addr, 0))
13190    {
13191        if (CurrentInstrSet() != eModeThumb)
13192        {
13193            SelectInstrSet(eModeThumb);
13194            cpsr_changed = true;
13195        }
13196        target = addr & 0xfffffffe;
13197        context.SetISA (eModeThumb);
13198    }
13199    else if (BitIsClear(addr, 1))
13200    {
13201        if (CurrentInstrSet() != eModeARM)
13202        {
13203            SelectInstrSet(eModeARM);
13204            cpsr_changed = true;
13205        }
13206        target = addr & 0xfffffffc;
13207        context.SetISA (eModeARM);
13208    }
13209    else
13210        return false; // address<1:0> == '10' => UNPREDICTABLE
13211
13212    if (cpsr_changed)
13213    {
13214        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13215            return false;
13216    }
13217    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13218        return false;
13219
13220    return true;
13221}
13222
13223// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13224bool
13225EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13226{
13227    if (ArchVersion() >= ARMv5T)
13228        return BXWritePC(context, addr);
13229    else
13230        return BranchWritePC((const Context)context, addr);
13231}
13232
13233// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13234bool
13235EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13236{
13237    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13238        return BXWritePC(context, addr);
13239    else
13240        return BranchWritePC((const Context)context, addr);
13241}
13242
13243EmulateInstructionARM::Mode
13244EmulateInstructionARM::CurrentInstrSet ()
13245{
13246    return m_opcode_mode;
13247}
13248
13249// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13250// ReadInstruction() is performed.  This function has a side effect of updating
13251// the m_new_inst_cpsr member variable if necessary.
13252bool
13253EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13254{
13255    m_new_inst_cpsr = m_opcode_cpsr;
13256    switch (arm_or_thumb)
13257    {
13258    default:
13259        return false;
13260    case eModeARM:
13261        // Clear the T bit.
13262        m_new_inst_cpsr &= ~MASK_CPSR_T;
13263        break;
13264    case eModeThumb:
13265        // Set the T bit.
13266        m_new_inst_cpsr |= MASK_CPSR_T;
13267        break;
13268    }
13269    return true;
13270}
13271
13272// This function returns TRUE if the processor currently provides support for
13273// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13274// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13275bool
13276EmulateInstructionARM::UnalignedSupport()
13277{
13278    return (ArchVersion() >= ARMv7);
13279}
13280
13281// The main addition and subtraction instructions can produce status information
13282// about both unsigned carry and signed overflow conditions.  This status
13283// information can be used to synthesize multi-word additions and subtractions.
13284EmulateInstructionARM::AddWithCarryResult
13285EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13286{
13287    uint32_t result;
13288    uint8_t carry_out;
13289    uint8_t overflow;
13290
13291    uint64_t unsigned_sum = x + y + carry_in;
13292    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13293
13294    result = UnsignedBits(unsigned_sum, 31, 0);
13295//    carry_out = (result == unsigned_sum ? 0 : 1);
13296    overflow = ((int32_t)result == signed_sum ? 0 : 1);
13297
13298    if (carry_in)
13299        carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13300    else
13301        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13302
13303    AddWithCarryResult res = { result, carry_out, overflow };
13304    return res;
13305}
13306
13307uint32_t
13308EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13309{
13310    uint32_t reg_kind, reg_num;
13311    switch (num)
13312    {
13313    case SP_REG:
13314        reg_kind = eRegisterKindGeneric;
13315        reg_num  = LLDB_REGNUM_GENERIC_SP;
13316        break;
13317    case LR_REG:
13318        reg_kind = eRegisterKindGeneric;
13319        reg_num  = LLDB_REGNUM_GENERIC_RA;
13320        break;
13321    case PC_REG:
13322        reg_kind = eRegisterKindGeneric;
13323        reg_num  = LLDB_REGNUM_GENERIC_PC;
13324        break;
13325    default:
13326        if (num < SP_REG)
13327        {
13328            reg_kind = eRegisterKindDWARF;
13329            reg_num  = dwarf_r0 + num;
13330        }
13331        else
13332        {
13333            //assert(0 && "Invalid register number");
13334            *success = false;
13335            return UINT32_MAX;
13336        }
13337        break;
13338    }
13339
13340    // Read our register.
13341    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13342
13343    // When executing an ARM instruction , PC reads as the address of the current
13344    // instruction plus 8.
13345    // When executing a Thumb instruction , PC reads as the address of the current
13346    // instruction plus 4.
13347    if (num == 15)
13348    {
13349        if (CurrentInstrSet() == eModeARM)
13350            val += 8;
13351        else
13352            val += 4;
13353    }
13354
13355    return val;
13356}
13357
13358// Write the result to the ARM core register Rd, and optionally update the
13359// condition flags based on the result.
13360//
13361// This helper method tries to encapsulate the following pseudocode from the
13362// ARM Architecture Reference Manual:
13363//
13364// if d == 15 then         // Can only occur for encoding A1
13365//     ALUWritePC(result); // setflags is always FALSE here
13366// else
13367//     R[d] = result;
13368//     if setflags then
13369//         APSR.N = result<31>;
13370//         APSR.Z = IsZeroBit(result);
13371//         APSR.C = carry;
13372//         // APSR.V unchanged
13373//
13374// In the above case, the API client does not pass in the overflow arg, which
13375// defaults to ~0u.
13376bool
13377EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13378                                                  const uint32_t result,
13379                                                  const uint32_t Rd,
13380                                                  bool setflags,
13381                                                  const uint32_t carry,
13382                                                  const uint32_t overflow)
13383{
13384    if (Rd == 15)
13385    {
13386        if (!ALUWritePC (context, result))
13387            return false;
13388    }
13389    else
13390    {
13391        uint32_t reg_kind, reg_num;
13392        switch (Rd)
13393        {
13394        case SP_REG:
13395            reg_kind = eRegisterKindGeneric;
13396            reg_num  = LLDB_REGNUM_GENERIC_SP;
13397            break;
13398        case LR_REG:
13399            reg_kind = eRegisterKindGeneric;
13400            reg_num  = LLDB_REGNUM_GENERIC_RA;
13401            break;
13402        default:
13403            reg_kind = eRegisterKindDWARF;
13404            reg_num  = dwarf_r0 + Rd;
13405        }
13406        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13407            return false;
13408        if (setflags)
13409            return WriteFlags (context, result, carry, overflow);
13410    }
13411    return true;
13412}
13413
13414// This helper method tries to encapsulate the following pseudocode from the
13415// ARM Architecture Reference Manual:
13416//
13417// APSR.N = result<31>;
13418// APSR.Z = IsZeroBit(result);
13419// APSR.C = carry;
13420// APSR.V = overflow
13421//
13422// Default arguments can be specified for carry and overflow parameters, which means
13423// not to update the respective flags.
13424bool
13425EmulateInstructionARM::WriteFlags (Context &context,
13426                                   const uint32_t result,
13427                                   const uint32_t carry,
13428                                   const uint32_t overflow)
13429{
13430    m_new_inst_cpsr = m_opcode_cpsr;
13431    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13432    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13433    if (carry != ~0u)
13434        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13435    if (overflow != ~0u)
13436        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13437    if (m_new_inst_cpsr != m_opcode_cpsr)
13438    {
13439        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13440            return false;
13441    }
13442    return true;
13443}
13444
13445bool
13446EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13447{
13448    // Advance the ITSTATE bits to their values for the next instruction.
13449    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13450        m_it_session.ITAdvance();
13451
13452    ARMOpcode *opcode_data = NULL;
13453
13454    if (m_opcode_mode == eModeThumb)
13455        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13456    else if (m_opcode_mode == eModeARM)
13457        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13458
13459    if (opcode_data == NULL)
13460        return false;
13461
13462    const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13463    m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13464
13465    bool success = false;
13466    if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13467    {
13468        m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13469                                                dwarf_cpsr,
13470                                                0,
13471                                                &success);
13472    }
13473
13474    // Only return false if we are unable to read the CPSR if we care about conditions
13475    if (success == false && m_ignore_conditions == false)
13476        return false;
13477
13478    uint32_t orig_pc_value = 0;
13479    if (auto_advance_pc)
13480    {
13481        orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13482        if (!success)
13483            return false;
13484    }
13485
13486    // Call the Emulate... function.
13487    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13488    if (!success)
13489        return false;
13490
13491    if (auto_advance_pc)
13492    {
13493        uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13494        if (!success)
13495            return false;
13496
13497        if (auto_advance_pc && (after_pc_value == orig_pc_value))
13498        {
13499            if (opcode_data->size == eSize32)
13500                after_pc_value += 4;
13501            else if (opcode_data->size == eSize16)
13502                after_pc_value += 2;
13503
13504            EmulateInstruction::Context context;
13505            context.type = eContextAdvancePC;
13506            context.SetNoArgs();
13507            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13508                return false;
13509
13510        }
13511    }
13512    return true;
13513}
13514
13515bool
13516EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13517{
13518    if (!test_data)
13519    {
13520        out_stream->Printf ("TestEmulation: Missing test data.\n");
13521        return false;
13522    }
13523
13524    static ConstString opcode_key ("opcode");
13525    static ConstString before_key ("before_state");
13526    static ConstString after_key ("after_state");
13527
13528    OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13529
13530    uint32_t test_opcode;
13531    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13532    {
13533        out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13534        return false;
13535    }
13536    test_opcode = value_sp->GetUInt64Value ();
13537
13538    if (arch.GetTriple().getArch() == llvm::Triple::arm)
13539    {
13540        m_opcode_mode = eModeARM;
13541        m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13542    }
13543    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13544    {
13545        m_opcode_mode = eModeThumb;
13546        if (test_opcode < 0x10000)
13547            m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13548        else
13549            m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13550
13551    }
13552    else
13553    {
13554        out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13555        return false;
13556    }
13557
13558    EmulationStateARM before_state;
13559    EmulationStateARM after_state;
13560
13561    value_sp = test_data->GetValueForKey (before_key);
13562    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13563    {
13564        out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13565        return false;
13566    }
13567
13568    OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13569    if (!before_state.LoadStateFromDictionary (state_dictionary))
13570    {
13571        out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13572        return false;
13573    }
13574
13575    value_sp = test_data->GetValueForKey (after_key);
13576    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13577    {
13578        out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13579        return false;
13580    }
13581
13582    state_dictionary = value_sp->GetAsDictionary ();
13583    if (!after_state.LoadStateFromDictionary (state_dictionary))
13584    {
13585        out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13586        return false;
13587    }
13588
13589    SetBaton ((void *) &before_state);
13590    SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13591                  &EmulationStateARM::WritePseudoMemory,
13592                  &EmulationStateARM::ReadPseudoRegister,
13593                  &EmulationStateARM::WritePseudoRegister);
13594
13595    bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13596    if (!success)
13597    {
13598        out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13599        return false;
13600    }
13601
13602    success = before_state.CompareState (after_state);
13603    if (!success)
13604        out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13605
13606    return success;
13607}
13608//
13609//
13610//const char *
13611//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13612//{
13613//    if (reg_kind == eRegisterKindGeneric)
13614//    {
13615//        switch (reg_num)
13616//        {
13617//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13618//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13619//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13620//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13621//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13622//        default: return NULL;
13623//        }
13624//    }
13625//    else if (reg_kind == eRegisterKindDWARF)
13626//    {
13627//        return GetARMDWARFRegisterName (reg_num);
13628//    }
13629//    return NULL;
13630//}
13631//
13632bool
13633EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13634{
13635    unwind_plan.Clear();
13636    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13637
13638    UnwindPlan::RowSP row(new UnwindPlan::Row);
13639
13640    // Our previous Call Frame Address is the stack pointer
13641    row->SetCFARegister (dwarf_sp);
13642
13643    // Our previous PC is in the LR
13644    row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13645    unwind_plan.AppendRow (row);
13646
13647    // All other registers are the same.
13648
13649    unwind_plan.SetSourceName ("EmulateInstructionARM");
13650    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13651    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13652    return true;
13653}
13654