EmulateInstructionARM.cpp revision 263508
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdlib.h>
11
12#include "EmulateInstructionARM.h"
13#include "EmulationStateARM.h"
14#include "lldb/Core/ArchSpec.h"
15#include "lldb/Core/Address.h"
16#include "lldb/Core/ConstString.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/Stream.h"
19#include "lldb/Interpreter/OptionValueArray.h"
20#include "lldb/Interpreter/OptionValueDictionary.h"
21#include "lldb/Symbol/UnwindPlan.h"
22
23#include "Plugins/Process/Utility/ARMDefines.h"
24#include "Plugins/Process/Utility/ARMUtils.h"
25#include "Utility/ARM_DWARF_Registers.h"
26
27#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
28                                     // and countTrailingZeros function
29
30using namespace lldb;
31using namespace lldb_private;
32
33// Convenient macro definitions.
34#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36
37#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38
39//----------------------------------------------------------------------
40//
41// ITSession implementation
42//
43//----------------------------------------------------------------------
44
45// A8.6.50
46// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
47static uint32_t
48CountITSize (uint32_t ITMask) {
49    // First count the trailing zeros of the IT mask.
50    uint32_t TZ = llvm::countTrailingZeros(ITMask);
51    if (TZ > 3)
52    {
53#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    if (m_opcode_mode == eModeThumb)
293    {
294        switch (m_arch.GetTriple().getOS())
295        {
296            case llvm::Triple::Darwin:
297            case llvm::Triple::MacOSX:
298            case llvm::Triple::IOS:
299                return 7;
300            default:
301                break;
302        }
303    }
304    return 11;
305}
306
307uint32_t
308EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
309{
310    if (m_opcode_mode == eModeThumb)
311    {
312        switch (m_arch.GetTriple().getOS())
313        {
314            case llvm::Triple::Darwin:
315            case llvm::Triple::MacOSX:
316            case llvm::Triple::IOS:
317                return dwarf_r7;
318            default:
319                break;
320        }
321    }
322    return dwarf_r11;
323}
324
325// Push Multiple Registers stores multiple registers to the stack, storing to
326// consecutive memory locations ending just below the address in SP, and updates
327// SP to point to the start of the stored data.
328bool
329EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
330{
331#if 0
332    // ARM pseudo code...
333    if (ConditionPassed())
334    {
335        EncodingSpecificOperations();
336        NullCheckIfThumbEE(13);
337        address = SP - 4*BitCount(registers);
338
339        for (i = 0 to 14)
340        {
341            if (registers<i> == '1')
342            {
343                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
344                    MemA[address,4] = bits(32) UNKNOWN;
345                else
346                    MemA[address,4] = R[i];
347                address = address + 4;
348            }
349        }
350
351        if (registers<15> == '1') // Only possible for encoding A1 or A2
352            MemA[address,4] = PCStoreValue();
353
354        SP = SP - 4*BitCount(registers);
355    }
356#endif
357
358    bool conditional = false;
359    bool success = false;
360    if (ConditionPassed(opcode, &conditional))
361    {
362        const uint32_t addr_byte_size = GetAddressByteSize();
363        const addr_t sp = ReadCoreReg (SP_REG, &success);
364        if (!success)
365            return false;
366        uint32_t registers = 0;
367        uint32_t Rt; // the source register
368        switch (encoding) {
369        case eEncodingT1:
370            registers = Bits32(opcode, 7, 0);
371            // The M bit represents LR.
372            if (Bit32(opcode, 8))
373                registers |= (1u << 14);
374            // if BitCount(registers) < 1 then UNPREDICTABLE;
375            if (BitCount(registers) < 1)
376                return false;
377            break;
378        case eEncodingT2:
379            // Ignore bits 15 & 13.
380            registers = Bits32(opcode, 15, 0) & ~0xa000;
381            // if BitCount(registers) < 2 then UNPREDICTABLE;
382            if (BitCount(registers) < 2)
383                return false;
384            break;
385        case eEncodingT3:
386            Rt = Bits32(opcode, 15, 12);
387            // if BadReg(t) then UNPREDICTABLE;
388            if (BadReg(Rt))
389                return false;
390            registers = (1u << Rt);
391            break;
392        case eEncodingA1:
393            registers = Bits32(opcode, 15, 0);
394            // Instead of return false, let's handle the following case as well,
395            // which amounts to pushing one reg onto the full descending stacks.
396            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
397            break;
398        case eEncodingA2:
399            Rt = Bits32(opcode, 15, 12);
400            // if t == 13 then UNPREDICTABLE;
401            if (Rt == dwarf_sp)
402                return false;
403            registers = (1u << Rt);
404            break;
405        default:
406            return false;
407        }
408        addr_t sp_offset = addr_byte_size * BitCount (registers);
409        addr_t addr = sp - sp_offset;
410        uint32_t i;
411
412        EmulateInstruction::Context context;
413        if (conditional)
414            context.type = EmulateInstruction::eContextRegisterStore;
415        else
416            context.type = EmulateInstruction::eContextPushRegisterOnStack;
417        RegisterInfo reg_info;
418        RegisterInfo sp_reg;
419        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
420        for (i=0; i<15; ++i)
421        {
422            if (BitIsSet (registers, i))
423            {
424                GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
425                context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
426                uint32_t reg_value = ReadCoreReg(i, &success);
427                if (!success)
428                    return false;
429                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
430                    return false;
431                addr += addr_byte_size;
432            }
433        }
434
435        if (BitIsSet (registers, 15))
436        {
437            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
438            context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
439            const uint32_t pc = ReadCoreReg(PC_REG, &success);
440            if (!success)
441                return false;
442            if (!MemAWrite (context, addr, pc, addr_byte_size))
443                return false;
444        }
445
446        context.type = EmulateInstruction::eContextAdjustStackPointer;
447        context.SetImmediateSigned (-sp_offset);
448
449        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
450            return false;
451    }
452    return true;
453}
454
455// Pop Multiple Registers loads multiple registers from the stack, loading from
456// consecutive memory locations staring at the address in SP, and updates
457// SP to point just above the loaded data.
458bool
459EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
460{
461#if 0
462    // ARM pseudo code...
463    if (ConditionPassed())
464    {
465        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
466        address = SP;
467        for i = 0 to 14
468            if registers<i> == '1' then
469                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
470        if registers<15> == '1' then
471            if UnalignedAllowed then
472                LoadWritePC(MemU[address,4]);
473            else
474                LoadWritePC(MemA[address,4]);
475        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
476        if registers<13> == '1' then SP = bits(32) UNKNOWN;
477    }
478#endif
479
480    bool success = false;
481
482    bool conditional = false;
483    if (ConditionPassed(opcode, &conditional))
484    {
485        const uint32_t addr_byte_size = GetAddressByteSize();
486        const addr_t sp = ReadCoreReg (SP_REG, &success);
487        if (!success)
488            return false;
489        uint32_t registers = 0;
490        uint32_t Rt; // the destination register
491        switch (encoding) {
492        case eEncodingT1:
493            registers = Bits32(opcode, 7, 0);
494            // The P bit represents PC.
495            if (Bit32(opcode, 8))
496                registers |= (1u << 15);
497            // if BitCount(registers) < 1 then UNPREDICTABLE;
498            if (BitCount(registers) < 1)
499                return false;
500            break;
501        case eEncodingT2:
502            // Ignore bit 13.
503            registers = Bits32(opcode, 15, 0) & ~0x2000;
504            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
505            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
506                return false;
507            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
508            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
509                return false;
510            break;
511        case eEncodingT3:
512            Rt = Bits32(opcode, 15, 12);
513            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
514            if (Rt == 13)
515                return false;
516            if (Rt == 15 && InITBlock() && !LastInITBlock())
517                return false;
518            registers = (1u << Rt);
519            break;
520        case eEncodingA1:
521            registers = Bits32(opcode, 15, 0);
522            // Instead of return false, let's handle the following case as well,
523            // which amounts to popping one reg from the full descending stacks.
524            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
525
526            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
527            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
528                return false;
529            break;
530        case eEncodingA2:
531            Rt = Bits32(opcode, 15, 12);
532            // if t == 13 then UNPREDICTABLE;
533            if (Rt == dwarf_sp)
534                return false;
535            registers = (1u << Rt);
536            break;
537        default:
538            return false;
539        }
540        addr_t sp_offset = addr_byte_size * BitCount (registers);
541        addr_t addr = sp;
542        uint32_t i, data;
543
544        EmulateInstruction::Context context;
545        if (conditional)
546            context.type = EmulateInstruction::eContextRegisterLoad;
547        else
548            context.type = EmulateInstruction::eContextPopRegisterOffStack;
549
550        RegisterInfo sp_reg;
551        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
552
553        for (i=0; i<15; ++i)
554        {
555            if (BitIsSet (registers, i))
556            {
557                context.SetRegisterPlusOffset (sp_reg, addr - sp);
558                data = MemARead(context, addr, 4, 0, &success);
559                if (!success)
560                    return false;
561                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
562                    return false;
563                addr += addr_byte_size;
564            }
565        }
566
567        if (BitIsSet (registers, 15))
568        {
569            context.SetRegisterPlusOffset (sp_reg, addr - sp);
570            data = MemARead(context, addr, 4, 0, &success);
571            if (!success)
572                return false;
573            // In ARMv5T and above, this is an interworking branch.
574            if (!LoadWritePC(context, data))
575                return false;
576            //addr += addr_byte_size;
577        }
578
579        context.type = EmulateInstruction::eContextAdjustStackPointer;
580        context.SetImmediateSigned (sp_offset);
581
582        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
583            return false;
584    }
585    return true;
586}
587
588// Set r7 or ip to point to saved value residing within the stack.
589// ADD (SP plus immediate)
590bool
591EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
592{
593#if 0
594    // ARM pseudo code...
595    if (ConditionPassed())
596    {
597        EncodingSpecificOperations();
598        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
599        if d == 15 then
600           ALUWritePC(result); // setflags is always FALSE here
601        else
602            R[d] = result;
603            if setflags then
604                APSR.N = result<31>;
605                APSR.Z = IsZeroBit(result);
606                APSR.C = carry;
607                APSR.V = overflow;
608    }
609#endif
610
611    bool success = false;
612
613    if (ConditionPassed(opcode))
614    {
615        const addr_t sp = ReadCoreReg (SP_REG, &success);
616        if (!success)
617            return false;
618        uint32_t Rd; // the destination register
619        uint32_t imm32;
620        switch (encoding) {
621        case eEncodingT1:
622            Rd = 7;
623            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
624            break;
625        case eEncodingA1:
626            Rd = Bits32(opcode, 15, 12);
627            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
628            break;
629        default:
630            return false;
631        }
632        addr_t sp_offset = imm32;
633        addr_t addr = sp + sp_offset; // a pointer to the stack area
634
635        EmulateInstruction::Context context;
636        context.type = eContextSetFramePointer;
637        RegisterInfo sp_reg;
638        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
639        context.SetRegisterPlusOffset (sp_reg, sp_offset);
640
641        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
642            return false;
643    }
644    return true;
645}
646
647// Set r7 or ip to the current stack pointer.
648// MOV (register)
649bool
650EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
651{
652#if 0
653    // ARM pseudo code...
654    if (ConditionPassed())
655    {
656        EncodingSpecificOperations();
657        result = R[m];
658        if d == 15 then
659            ALUWritePC(result); // setflags is always FALSE here
660        else
661            R[d] = result;
662            if setflags then
663                APSR.N = result<31>;
664                APSR.Z = IsZeroBit(result);
665                // APSR.C unchanged
666                // APSR.V unchanged
667    }
668#endif
669
670    bool success = false;
671
672    if (ConditionPassed(opcode))
673    {
674        const addr_t sp = ReadCoreReg (SP_REG, &success);
675        if (!success)
676            return false;
677        uint32_t Rd; // the destination register
678        switch (encoding) {
679        case eEncodingT1:
680            Rd = 7;
681            break;
682        case eEncodingA1:
683            Rd = 12;
684            break;
685        default:
686            return false;
687        }
688
689        EmulateInstruction::Context context;
690        if (Rd == GetFramePointerRegisterNumber())
691            context.type = EmulateInstruction::eContextSetFramePointer;
692        else
693            context.type = EmulateInstruction::eContextRegisterPlusOffset;
694        RegisterInfo sp_reg;
695        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
696        context.SetRegisterPlusOffset (sp_reg, 0);
697
698        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
699            return false;
700    }
701    return true;
702}
703
704// Move from high register (r8-r15) to low register (r0-r7).
705// MOV (register)
706bool
707EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
708{
709    return EmulateMOVRdRm (opcode, encoding);
710}
711
712// Move from register to register.
713// MOV (register)
714bool
715EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
716{
717#if 0
718    // ARM pseudo code...
719    if (ConditionPassed())
720    {
721        EncodingSpecificOperations();
722        result = R[m];
723        if d == 15 then
724            ALUWritePC(result); // setflags is always FALSE here
725        else
726            R[d] = result;
727            if setflags then
728                APSR.N = result<31>;
729                APSR.Z = IsZeroBit(result);
730                // APSR.C unchanged
731                // APSR.V unchanged
732    }
733#endif
734
735    bool success = false;
736
737    if (ConditionPassed(opcode))
738    {
739        uint32_t Rm; // the source register
740        uint32_t Rd; // the destination register
741        bool setflags;
742        switch (encoding) {
743        case eEncodingT1:
744            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
745            Rm = Bits32(opcode, 6, 3);
746            setflags = false;
747            if (Rd == 15 && InITBlock() && !LastInITBlock())
748                return false;
749            break;
750        case eEncodingT2:
751            Rd = Bits32(opcode, 2, 0);
752            Rm = Bits32(opcode, 5, 3);
753            setflags = true;
754            if (InITBlock())
755                return false;
756            break;
757        case eEncodingT3:
758            Rd = Bits32(opcode, 11, 8);
759            Rm = Bits32(opcode, 3, 0);
760            setflags = BitIsSet(opcode, 20);
761            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
762            if (setflags && (BadReg(Rd) || BadReg(Rm)))
763                return false;
764            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
765            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
766                return false;
767            break;
768        case eEncodingA1:
769            Rd = Bits32(opcode, 15, 12);
770            Rm = Bits32(opcode, 3, 0);
771            setflags = BitIsSet(opcode, 20);
772
773            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
774            if (Rd == 15 && setflags)
775                return EmulateSUBSPcLrEtc (opcode, encoding);
776            break;
777        default:
778            return false;
779        }
780        uint32_t result = ReadCoreReg(Rm, &success);
781        if (!success)
782            return false;
783
784        // The context specifies that Rm is to be moved into Rd.
785        EmulateInstruction::Context context;
786        context.type = EmulateInstruction::eContextRegisterLoad;
787        RegisterInfo dwarf_reg;
788        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
789        context.SetRegister (dwarf_reg);
790
791        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
792            return false;
793    }
794    return true;
795}
796
797// Move (immediate) writes an immediate value to the destination register.  It
798// can optionally update the condition flags based on the value.
799// MOV (immediate)
800bool
801EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
802{
803#if 0
804    // ARM pseudo code...
805    if (ConditionPassed())
806    {
807        EncodingSpecificOperations();
808        result = imm32;
809        if d == 15 then         // Can only occur for ARM encoding
810            ALUWritePC(result); // setflags is always FALSE here
811        else
812            R[d] = result;
813            if setflags then
814                APSR.N = result<31>;
815                APSR.Z = IsZeroBit(result);
816                APSR.C = carry;
817                // APSR.V unchanged
818    }
819#endif
820
821    if (ConditionPassed(opcode))
822    {
823        uint32_t Rd; // the destination register
824        uint32_t imm32; // the immediate value to be written to Rd
825        uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
826                            // for setflags == false, this value is a don't care
827                            // initialized to 0 to silence the static analyzer
828        bool setflags;
829        switch (encoding) {
830            case eEncodingT1:
831                Rd = Bits32(opcode, 10, 8);
832                setflags = !InITBlock();
833                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
834                carry = APSR_C;
835
836                break;
837
838            case eEncodingT2:
839                Rd = Bits32(opcode, 11, 8);
840                setflags = BitIsSet(opcode, 20);
841                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
842                if (BadReg(Rd))
843                  return false;
844
845                break;
846
847            case eEncodingT3:
848            {
849                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
850                Rd = Bits32 (opcode, 11, 8);
851                setflags = false;
852                uint32_t imm4 = Bits32 (opcode, 19, 16);
853                uint32_t imm3 = Bits32 (opcode, 14, 12);
854                uint32_t i = Bit32 (opcode, 26);
855                uint32_t imm8 = Bits32 (opcode, 7, 0);
856                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
857
858                // if BadReg(d) then UNPREDICTABLE;
859                if (BadReg (Rd))
860                    return false;
861            }
862                break;
863
864            case eEncodingA1:
865                // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
866                Rd = Bits32 (opcode, 15, 12);
867                setflags = BitIsSet (opcode, 20);
868                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
869
870                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
871                if ((Rd == 15) && setflags)
872                    return EmulateSUBSPcLrEtc (opcode, encoding);
873
874                break;
875
876            case eEncodingA2:
877            {
878                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
879                Rd = Bits32 (opcode, 15, 12);
880                setflags = false;
881                uint32_t imm4 = Bits32 (opcode, 19, 16);
882                uint32_t imm12 = Bits32 (opcode, 11, 0);
883                imm32 = (imm4 << 12) | imm12;
884
885                // if d == 15 then UNPREDICTABLE;
886                if (Rd == 15)
887                    return false;
888            }
889                break;
890
891            default:
892                return false;
893        }
894        uint32_t result = imm32;
895
896        // The context specifies that an immediate is to be moved into Rd.
897        EmulateInstruction::Context context;
898        context.type = EmulateInstruction::eContextImmediate;
899        context.SetNoArgs ();
900
901        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
902            return false;
903    }
904    return true;
905}
906
907// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
908// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
909// unsigned values.
910//
911// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
912// limited to only a few forms of the instruction.
913bool
914EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
915{
916#if 0
917    if ConditionPassed() then
918        EncodingSpecificOperations();
919        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
920        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
921        result = operand1 * operand2;
922        R[d] = result<31:0>;
923        if setflags then
924            APSR.N = result<31>;
925            APSR.Z = IsZeroBit(result);
926            if ArchVersion() == 4 then
927                APSR.C = bit UNKNOWN;
928            // else APSR.C unchanged
929            // APSR.V always unchanged
930#endif
931
932    if (ConditionPassed(opcode))
933    {
934        uint32_t d;
935        uint32_t n;
936        uint32_t m;
937        bool setflags;
938
939        // EncodingSpecificOperations();
940        switch (encoding)
941        {
942            case eEncodingT1:
943                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
944                d = Bits32 (opcode, 2, 0);
945                n = Bits32 (opcode, 5, 3);
946                m = Bits32 (opcode, 2, 0);
947                setflags = !InITBlock();
948
949                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
950                if ((ArchVersion() < ARMv6) && (d == n))
951                    return false;
952
953                break;
954
955            case eEncodingT2:
956                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
957                d = Bits32 (opcode, 11, 8);
958                n = Bits32 (opcode, 19, 16);
959                m = Bits32 (opcode, 3, 0);
960                setflags = false;
961
962                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
963                if (BadReg (d) || BadReg (n) || BadReg (m))
964                    return false;
965
966                break;
967
968            case eEncodingA1:
969                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
970                d = Bits32 (opcode, 19, 16);
971                n = Bits32 (opcode, 3, 0);
972                m = Bits32 (opcode, 11, 8);
973                setflags = BitIsSet (opcode, 20);
974
975                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
976                if ((d == 15) ||  (n == 15) || (m == 15))
977                    return false;
978
979                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
980                if ((ArchVersion() < ARMv6) && (d == n))
981                    return false;
982
983                break;
984
985            default:
986                return false;
987        }
988
989        bool success = false;
990
991        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
992        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
993        if (!success)
994            return false;
995
996        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
997        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
998        if (!success)
999            return false;
1000
1001        // result = operand1 * operand2;
1002        uint64_t result = operand1 * operand2;
1003
1004        // R[d] = result<31:0>;
1005        RegisterInfo op1_reg;
1006        RegisterInfo op2_reg;
1007        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1008        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1009
1010        EmulateInstruction::Context context;
1011        context.type = eContextArithmetic;
1012        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1013
1014        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1015            return false;
1016
1017        // if setflags then
1018        if (setflags)
1019        {
1020            // APSR.N = result<31>;
1021            // APSR.Z = IsZeroBit(result);
1022            m_new_inst_cpsr = m_opcode_cpsr;
1023            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1024            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1025            if (m_new_inst_cpsr != m_opcode_cpsr)
1026            {
1027                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1028                    return false;
1029            }
1030
1031            // if ArchVersion() == 4 then
1032                // APSR.C = bit UNKNOWN;
1033        }
1034    }
1035    return true;
1036}
1037
1038// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1039// It can optionally update the condition flags based on the value.
1040bool
1041EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1042{
1043#if 0
1044    // ARM pseudo code...
1045    if (ConditionPassed())
1046    {
1047        EncodingSpecificOperations();
1048        result = NOT(imm32);
1049        if d == 15 then         // Can only occur for ARM encoding
1050            ALUWritePC(result); // setflags is always FALSE here
1051        else
1052            R[d] = result;
1053            if setflags then
1054                APSR.N = result<31>;
1055                APSR.Z = IsZeroBit(result);
1056                APSR.C = carry;
1057                // APSR.V unchanged
1058    }
1059#endif
1060
1061    if (ConditionPassed(opcode))
1062    {
1063        uint32_t Rd; // the destination register
1064        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1065        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1066        bool setflags;
1067        switch (encoding) {
1068        case eEncodingT1:
1069            Rd = Bits32(opcode, 11, 8);
1070            setflags = BitIsSet(opcode, 20);
1071            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1072            break;
1073        case eEncodingA1:
1074            Rd = Bits32(opcode, 15, 12);
1075            setflags = BitIsSet(opcode, 20);
1076            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1077
1078            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1079            if (Rd == 15 && setflags)
1080                return EmulateSUBSPcLrEtc (opcode, encoding);
1081            break;
1082        default:
1083            return false;
1084        }
1085        uint32_t result = ~imm32;
1086
1087        // The context specifies that an immediate is to be moved into Rd.
1088        EmulateInstruction::Context context;
1089        context.type = EmulateInstruction::eContextImmediate;
1090        context.SetNoArgs ();
1091
1092        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1093            return false;
1094    }
1095    return true;
1096}
1097
1098// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1099// It can optionally update the condition flags based on the result.
1100bool
1101EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1102{
1103#if 0
1104    // ARM pseudo code...
1105    if (ConditionPassed())
1106    {
1107        EncodingSpecificOperations();
1108        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1109        result = NOT(shifted);
1110        if d == 15 then         // Can only occur for ARM encoding
1111            ALUWritePC(result); // setflags is always FALSE here
1112        else
1113            R[d] = result;
1114            if setflags then
1115                APSR.N = result<31>;
1116                APSR.Z = IsZeroBit(result);
1117                APSR.C = carry;
1118                // APSR.V unchanged
1119    }
1120#endif
1121
1122    if (ConditionPassed(opcode))
1123    {
1124        uint32_t Rm; // the source register
1125        uint32_t Rd; // the destination register
1126        ARM_ShifterType shift_t;
1127        uint32_t shift_n; // the shift applied to the value read from Rm
1128        bool setflags;
1129        uint32_t carry; // the carry bit after the shift operation
1130        switch (encoding) {
1131        case eEncodingT1:
1132            Rd = Bits32(opcode, 2, 0);
1133            Rm = Bits32(opcode, 5, 3);
1134            setflags = !InITBlock();
1135            shift_t = SRType_LSL;
1136            shift_n = 0;
1137            if (InITBlock())
1138                return false;
1139            break;
1140        case eEncodingT2:
1141            Rd = Bits32(opcode, 11, 8);
1142            Rm = Bits32(opcode, 3, 0);
1143            setflags = BitIsSet(opcode, 20);
1144            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1145            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1146            if (BadReg(Rd) || BadReg(Rm))
1147                return false;
1148            break;
1149        case eEncodingA1:
1150            Rd = Bits32(opcode, 15, 12);
1151            Rm = Bits32(opcode, 3, 0);
1152            setflags = BitIsSet(opcode, 20);
1153            shift_n = DecodeImmShiftARM(opcode, shift_t);
1154            break;
1155        default:
1156            return false;
1157        }
1158        bool success = false;
1159        uint32_t value = ReadCoreReg(Rm, &success);
1160        if (!success)
1161            return false;
1162
1163        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1164        if (!success)
1165            return false;
1166        uint32_t result = ~shifted;
1167
1168        // The context specifies that an immediate is to be moved into Rd.
1169        EmulateInstruction::Context context;
1170        context.type = EmulateInstruction::eContextImmediate;
1171        context.SetNoArgs ();
1172
1173        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1174            return false;
1175    }
1176    return true;
1177}
1178
1179// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1180// LDR (literal)
1181bool
1182EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1183{
1184#if 0
1185    // ARM pseudo code...
1186    if (ConditionPassed())
1187    {
1188        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1189        base = Align(PC,4);
1190        address = if add then (base + imm32) else (base - imm32);
1191        data = MemU[address,4];
1192        if t == 15 then
1193            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1194        elsif UnalignedSupport() || address<1:0> = '00' then
1195            R[t] = data;
1196        else // Can only apply before ARMv7
1197            if CurrentInstrSet() == InstrSet_ARM then
1198                R[t] = ROR(data, 8*UInt(address<1:0>));
1199            else
1200                R[t] = bits(32) UNKNOWN;
1201    }
1202#endif
1203
1204    if (ConditionPassed(opcode))
1205    {
1206        bool success = false;
1207        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1208        if (!success)
1209            return false;
1210
1211        // PC relative immediate load context
1212        EmulateInstruction::Context context;
1213        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1214        RegisterInfo pc_reg;
1215        GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1216        context.SetRegisterPlusOffset (pc_reg, 0);
1217
1218        uint32_t Rt;    // the destination register
1219        uint32_t imm32; // immediate offset from the PC
1220        bool add;       // +imm32 or -imm32?
1221        addr_t base;    // the base address
1222        addr_t address; // the PC relative address
1223        uint32_t data;  // the literal data value from the PC relative load
1224        switch (encoding) {
1225        case eEncodingT1:
1226            Rt = Bits32(opcode, 10, 8);
1227            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1228            add = true;
1229            break;
1230        case eEncodingT2:
1231            Rt = Bits32(opcode, 15, 12);
1232            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1233            add = BitIsSet(opcode, 23);
1234            if (Rt == 15 && InITBlock() && !LastInITBlock())
1235                return false;
1236            break;
1237        default:
1238            return false;
1239        }
1240
1241        base = Align(pc, 4);
1242        if (add)
1243            address = base + imm32;
1244        else
1245            address = base - imm32;
1246
1247        context.SetRegisterPlusOffset(pc_reg, address - base);
1248        data = MemURead(context, address, 4, 0, &success);
1249        if (!success)
1250            return false;
1251
1252        if (Rt == 15)
1253        {
1254            if (Bits32(address, 1, 0) == 0)
1255            {
1256                // In ARMv5T and above, this is an interworking branch.
1257                if (!LoadWritePC(context, data))
1258                    return false;
1259            }
1260            else
1261                return false;
1262        }
1263        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1264        {
1265            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1266                return false;
1267        }
1268        else // We don't handle ARM for now.
1269            return false;
1270
1271    }
1272    return true;
1273}
1274
1275// An add operation to adjust the SP.
1276// ADD (SP plus immediate)
1277bool
1278EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1279{
1280#if 0
1281    // ARM pseudo code...
1282    if (ConditionPassed())
1283    {
1284        EncodingSpecificOperations();
1285        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1286        if d == 15 then // Can only occur for ARM encoding
1287            ALUWritePC(result); // setflags is always FALSE here
1288        else
1289            R[d] = result;
1290            if setflags then
1291                APSR.N = result<31>;
1292                APSR.Z = IsZeroBit(result);
1293                APSR.C = carry;
1294                APSR.V = overflow;
1295    }
1296#endif
1297
1298    bool success = false;
1299
1300    if (ConditionPassed(opcode))
1301    {
1302        const addr_t sp = ReadCoreReg (SP_REG, &success);
1303        if (!success)
1304            return false;
1305        uint32_t imm32; // the immediate operand
1306        uint32_t d;
1307        //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1308        switch (encoding)
1309        {
1310            case eEncodingT1:
1311                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1312                d = Bits32 (opcode, 10, 8);
1313                imm32 = (Bits32 (opcode, 7, 0) << 2);
1314
1315                break;
1316
1317            case eEncodingT2:
1318                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1319                d = 13;
1320                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1321
1322                break;
1323
1324            default:
1325                return false;
1326        }
1327        addr_t sp_offset = imm32;
1328        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1329
1330        EmulateInstruction::Context context;
1331        context.type = EmulateInstruction::eContextAdjustStackPointer;
1332        RegisterInfo sp_reg;
1333        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1334        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1335
1336        if (d == 15)
1337        {
1338            if (!ALUWritePC (context, addr))
1339                return false;
1340        }
1341        else
1342        {
1343            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1344                return false;
1345
1346            // Add this back if/when support eEncodingT3 eEncodingA1
1347            //if (setflags)
1348            //{
1349            //    APSR.N = result<31>;
1350            //    APSR.Z = IsZeroBit(result);
1351            //    APSR.C = carry;
1352            //    APSR.V = overflow;
1353            //}
1354        }
1355    }
1356    return true;
1357}
1358
1359// An add operation to adjust the SP.
1360// ADD (SP plus register)
1361bool
1362EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1363{
1364#if 0
1365    // ARM pseudo code...
1366    if (ConditionPassed())
1367    {
1368        EncodingSpecificOperations();
1369        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1370        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1371        if d == 15 then
1372            ALUWritePC(result); // setflags is always FALSE here
1373        else
1374            R[d] = result;
1375            if setflags then
1376                APSR.N = result<31>;
1377                APSR.Z = IsZeroBit(result);
1378                APSR.C = carry;
1379                APSR.V = overflow;
1380    }
1381#endif
1382
1383    bool success = false;
1384
1385    if (ConditionPassed(opcode))
1386    {
1387        const addr_t sp = ReadCoreReg (SP_REG, &success);
1388        if (!success)
1389            return false;
1390        uint32_t Rm; // the second operand
1391        switch (encoding) {
1392        case eEncodingT2:
1393            Rm = Bits32(opcode, 6, 3);
1394            break;
1395        default:
1396            return false;
1397        }
1398        int32_t reg_value = ReadCoreReg(Rm, &success);
1399        if (!success)
1400            return false;
1401
1402        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1403
1404        EmulateInstruction::Context context;
1405        context.type = eContextArithmetic;
1406        RegisterInfo sp_reg;
1407        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1408
1409        RegisterInfo other_reg;
1410        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1411        context.SetRegisterRegisterOperands (sp_reg, other_reg);
1412
1413        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1414            return false;
1415    }
1416    return true;
1417}
1418
1419// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1420// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1421// from Thumb to ARM.
1422// BLX (immediate)
1423bool
1424EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1425{
1426#if 0
1427    // ARM pseudo code...
1428    if (ConditionPassed())
1429    {
1430        EncodingSpecificOperations();
1431        if CurrentInstrSet() == InstrSet_ARM then
1432            LR = PC - 4;
1433        else
1434            LR = PC<31:1> : '1';
1435        if targetInstrSet == InstrSet_ARM then
1436            targetAddress = Align(PC,4) + imm32;
1437        else
1438            targetAddress = PC + imm32;
1439        SelectInstrSet(targetInstrSet);
1440        BranchWritePC(targetAddress);
1441    }
1442#endif
1443
1444    bool success = true;
1445
1446    if (ConditionPassed(opcode))
1447    {
1448        EmulateInstruction::Context context;
1449        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1450        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1451        if (!success)
1452            return false;
1453        addr_t lr; // next instruction address
1454        addr_t target; // target address
1455        int32_t imm32; // PC-relative offset
1456        switch (encoding) {
1457        case eEncodingT1:
1458            {
1459            lr = pc | 1u; // return address
1460            uint32_t S = Bit32(opcode, 26);
1461            uint32_t imm10 = Bits32(opcode, 25, 16);
1462            uint32_t J1 = Bit32(opcode, 13);
1463            uint32_t J2 = Bit32(opcode, 11);
1464            uint32_t imm11 = Bits32(opcode, 10, 0);
1465            uint32_t I1 = !(J1 ^ S);
1466            uint32_t I2 = !(J2 ^ S);
1467            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1468            imm32 = llvm::SignExtend32<25>(imm25);
1469            target = pc + imm32;
1470            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1471            if (InITBlock() && !LastInITBlock())
1472                return false;
1473            break;
1474            }
1475        case eEncodingT2:
1476            {
1477            lr = pc | 1u; // return address
1478            uint32_t S = Bit32(opcode, 26);
1479            uint32_t imm10H = Bits32(opcode, 25, 16);
1480            uint32_t J1 = Bit32(opcode, 13);
1481            uint32_t J2 = Bit32(opcode, 11);
1482            uint32_t imm10L = Bits32(opcode, 10, 1);
1483            uint32_t I1 = !(J1 ^ S);
1484            uint32_t I2 = !(J2 ^ S);
1485            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1486            imm32 = llvm::SignExtend32<25>(imm25);
1487            target = Align(pc, 4) + imm32;
1488            context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1489            if (InITBlock() && !LastInITBlock())
1490                return false;
1491            break;
1492            }
1493        case eEncodingA1:
1494            lr = pc - 4; // return address
1495            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1496            target = Align(pc, 4) + imm32;
1497            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1498            break;
1499        case eEncodingA2:
1500            lr = pc - 4; // return address
1501            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1502            target = pc + imm32;
1503            context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1504            break;
1505        default:
1506            return false;
1507        }
1508        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1509            return false;
1510        if (!BranchWritePC(context, target))
1511            return false;
1512    }
1513    return true;
1514}
1515
1516// Branch with Link and Exchange (register) calls a subroutine at an address and
1517// instruction set specified by a register.
1518// BLX (register)
1519bool
1520EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1521{
1522#if 0
1523    // ARM pseudo code...
1524    if (ConditionPassed())
1525    {
1526        EncodingSpecificOperations();
1527        target = R[m];
1528        if CurrentInstrSet() == InstrSet_ARM then
1529            next_instr_addr = PC - 4;
1530            LR = next_instr_addr;
1531        else
1532            next_instr_addr = PC - 2;
1533            LR = next_instr_addr<31:1> : '1';
1534        BXWritePC(target);
1535    }
1536#endif
1537
1538    bool success = false;
1539
1540    if (ConditionPassed(opcode))
1541    {
1542        EmulateInstruction::Context context;
1543        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1544        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1545        addr_t lr; // next instruction address
1546        if (!success)
1547            return false;
1548        uint32_t Rm; // the register with the target address
1549        switch (encoding) {
1550        case eEncodingT1:
1551            lr = (pc - 2) | 1u; // return address
1552            Rm = Bits32(opcode, 6, 3);
1553            // if m == 15 then UNPREDICTABLE;
1554            if (Rm == 15)
1555                return false;
1556            if (InITBlock() && !LastInITBlock())
1557                return false;
1558            break;
1559        case eEncodingA1:
1560            lr = pc - 4; // return address
1561            Rm = Bits32(opcode, 3, 0);
1562            // if m == 15 then UNPREDICTABLE;
1563            if (Rm == 15)
1564                return false;
1565            break;
1566        default:
1567            return false;
1568        }
1569        addr_t target = ReadCoreReg (Rm, &success);
1570        if (!success)
1571            return false;
1572        RegisterInfo dwarf_reg;
1573        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1574        context.SetRegister (dwarf_reg);
1575        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1576            return false;
1577        if (!BXWritePC(context, target))
1578            return false;
1579    }
1580    return true;
1581}
1582
1583// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1584bool
1585EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1586{
1587#if 0
1588    // ARM pseudo code...
1589    if (ConditionPassed())
1590    {
1591        EncodingSpecificOperations();
1592        BXWritePC(R[m]);
1593    }
1594#endif
1595
1596    if (ConditionPassed(opcode))
1597    {
1598        EmulateInstruction::Context context;
1599        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1600        uint32_t Rm; // the register with the target address
1601        switch (encoding) {
1602        case eEncodingT1:
1603            Rm = Bits32(opcode, 6, 3);
1604            if (InITBlock() && !LastInITBlock())
1605                return false;
1606            break;
1607        case eEncodingA1:
1608            Rm = Bits32(opcode, 3, 0);
1609            break;
1610        default:
1611            return false;
1612        }
1613        bool success = false;
1614        addr_t target = ReadCoreReg (Rm, &success);
1615        if (!success)
1616            return false;
1617
1618        RegisterInfo dwarf_reg;
1619        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1620        context.SetRegister (dwarf_reg);
1621        if (!BXWritePC(context, target))
1622            return false;
1623    }
1624    return true;
1625}
1626
1627// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1628// address and instruction set specified by a register as though it were a BX instruction.
1629//
1630// TODO: Emulate Jazelle architecture?
1631//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1632bool
1633EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1634{
1635#if 0
1636    // ARM pseudo code...
1637    if (ConditionPassed())
1638    {
1639        EncodingSpecificOperations();
1640        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1641            BXWritePC(R[m]);
1642        else
1643            if JazelleAcceptsExecution() then
1644                SwitchToJazelleExecution();
1645            else
1646                SUBARCHITECTURE_DEFINED handler call;
1647    }
1648#endif
1649
1650    if (ConditionPassed(opcode))
1651    {
1652        EmulateInstruction::Context context;
1653        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1654        uint32_t Rm; // the register with the target address
1655        switch (encoding) {
1656        case eEncodingT1:
1657            Rm = Bits32(opcode, 19, 16);
1658            if (BadReg(Rm))
1659                return false;
1660            if (InITBlock() && !LastInITBlock())
1661                return false;
1662            break;
1663        case eEncodingA1:
1664            Rm = Bits32(opcode, 3, 0);
1665            if (Rm == 15)
1666                return false;
1667            break;
1668        default:
1669            return false;
1670        }
1671        bool success = false;
1672        addr_t target = ReadCoreReg (Rm, &success);
1673        if (!success)
1674            return false;
1675
1676        RegisterInfo dwarf_reg;
1677        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1678        context.SetRegister (dwarf_reg);
1679        if (!BXWritePC(context, target))
1680            return false;
1681    }
1682    return true;
1683}
1684
1685// Set r7 to point to some ip offset.
1686// SUB (immediate)
1687bool
1688EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1689{
1690#if 0
1691    // ARM pseudo code...
1692    if (ConditionPassed())
1693    {
1694        EncodingSpecificOperations();
1695        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1696        if d == 15 then // Can only occur for ARM encoding
1697           ALUWritePC(result); // setflags is always FALSE here
1698        else
1699            R[d] = result;
1700            if setflags then
1701                APSR.N = result<31>;
1702                APSR.Z = IsZeroBit(result);
1703                APSR.C = carry;
1704                APSR.V = overflow;
1705    }
1706#endif
1707
1708    if (ConditionPassed(opcode))
1709    {
1710        bool success = false;
1711        const addr_t ip = ReadCoreReg (12, &success);
1712        if (!success)
1713            return false;
1714        uint32_t imm32;
1715        switch (encoding) {
1716        case eEncodingA1:
1717            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1718            break;
1719        default:
1720            return false;
1721        }
1722        addr_t ip_offset = imm32;
1723        addr_t addr = ip - ip_offset; // the adjusted ip value
1724
1725        EmulateInstruction::Context context;
1726        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1727        RegisterInfo dwarf_reg;
1728        GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1729        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1730
1731        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1732            return false;
1733    }
1734    return true;
1735}
1736
1737// Set ip to point to some stack offset.
1738// SUB (SP minus immediate)
1739bool
1740EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1741{
1742#if 0
1743    // ARM pseudo code...
1744    if (ConditionPassed())
1745    {
1746        EncodingSpecificOperations();
1747        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1748        if d == 15 then // Can only occur for ARM encoding
1749           ALUWritePC(result); // setflags is always FALSE here
1750        else
1751            R[d] = result;
1752            if setflags then
1753                APSR.N = result<31>;
1754                APSR.Z = IsZeroBit(result);
1755                APSR.C = carry;
1756                APSR.V = overflow;
1757    }
1758#endif
1759
1760    if (ConditionPassed(opcode))
1761    {
1762        bool success = false;
1763        const addr_t sp = ReadCoreReg (SP_REG, &success);
1764        if (!success)
1765            return false;
1766        uint32_t imm32;
1767        switch (encoding) {
1768        case eEncodingA1:
1769            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1770            break;
1771        default:
1772            return false;
1773        }
1774        addr_t sp_offset = imm32;
1775        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1776
1777        EmulateInstruction::Context context;
1778        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1779        RegisterInfo dwarf_reg;
1780        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1781        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1782
1783        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1784            return false;
1785    }
1786    return true;
1787}
1788
1789// This instruction subtracts an immediate value from the SP value, and writes
1790// the result to the destination register.
1791//
1792// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1793bool
1794EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1795{
1796#if 0
1797    // ARM pseudo code...
1798    if (ConditionPassed())
1799    {
1800        EncodingSpecificOperations();
1801        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1802        if d == 15 then        // Can only occur for ARM encoding
1803           ALUWritePC(result); // setflags is always FALSE here
1804        else
1805            R[d] = result;
1806            if setflags then
1807                APSR.N = result<31>;
1808                APSR.Z = IsZeroBit(result);
1809                APSR.C = carry;
1810                APSR.V = overflow;
1811    }
1812#endif
1813
1814    bool success = false;
1815    if (ConditionPassed(opcode))
1816    {
1817        const addr_t sp = ReadCoreReg (SP_REG, &success);
1818        if (!success)
1819            return false;
1820
1821        uint32_t Rd;
1822        bool setflags;
1823        uint32_t imm32;
1824        switch (encoding) {
1825        case eEncodingT1:
1826            Rd = 13;
1827            setflags = false;
1828            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1829            break;
1830        case eEncodingT2:
1831            Rd = Bits32(opcode, 11, 8);
1832            setflags = BitIsSet(opcode, 20);
1833            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1834            if (Rd == 15 && setflags)
1835                return EmulateCMPImm(opcode, eEncodingT2);
1836            if (Rd == 15 && !setflags)
1837                return false;
1838            break;
1839        case eEncodingT3:
1840            Rd = Bits32(opcode, 11, 8);
1841            setflags = false;
1842            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1843            if (Rd == 15)
1844                return false;
1845            break;
1846        case eEncodingA1:
1847            Rd = Bits32(opcode, 15, 12);
1848            setflags = BitIsSet(opcode, 20);
1849            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1850
1851            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1852            if (Rd == 15 && setflags)
1853                return EmulateSUBSPcLrEtc (opcode, encoding);
1854            break;
1855        default:
1856            return false;
1857        }
1858        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1859
1860        EmulateInstruction::Context context;
1861        if (Rd == 13)
1862        {
1863            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1864                                     // value gets passed down to context.SetImmediateSigned.
1865            context.type = EmulateInstruction::eContextAdjustStackPointer;
1866            context.SetImmediateSigned (-imm64); // the stack pointer offset
1867        }
1868        else
1869        {
1870            context.type = EmulateInstruction::eContextImmediate;
1871            context.SetNoArgs ();
1872        }
1873
1874        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1875            return false;
1876    }
1877    return true;
1878}
1879
1880// A store operation to the stack that also updates the SP.
1881bool
1882EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1883{
1884#if 0
1885    // ARM pseudo code...
1886    if (ConditionPassed())
1887    {
1888        EncodingSpecificOperations();
1889        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1890        address = if index then offset_addr else R[n];
1891        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1892        if wback then R[n] = offset_addr;
1893    }
1894#endif
1895
1896    bool conditional = false;
1897    bool success = false;
1898    if (ConditionPassed(opcode, &conditional))
1899    {
1900        const uint32_t addr_byte_size = GetAddressByteSize();
1901        const addr_t sp = ReadCoreReg (SP_REG, &success);
1902        if (!success)
1903            return false;
1904        uint32_t Rt; // the source register
1905        uint32_t imm12;
1906        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1907
1908        bool index;
1909        bool add;
1910        bool wback;
1911        switch (encoding) {
1912        case eEncodingA1:
1913            Rt = Bits32(opcode, 15, 12);
1914            imm12 = Bits32(opcode, 11, 0);
1915            Rn = Bits32 (opcode, 19, 16);
1916
1917            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1918                return false;
1919
1920            index = BitIsSet (opcode, 24);
1921            add = BitIsSet (opcode, 23);
1922            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1923
1924            if (wback && ((Rn == 15) || (Rn == Rt)))
1925                return false;
1926            break;
1927        default:
1928            return false;
1929        }
1930        addr_t offset_addr;
1931        if (add)
1932            offset_addr = sp + imm12;
1933        else
1934            offset_addr = sp - imm12;
1935
1936        addr_t addr;
1937        if (index)
1938            addr = offset_addr;
1939        else
1940            addr = sp;
1941
1942        EmulateInstruction::Context context;
1943        if (conditional)
1944            context.type = EmulateInstruction::eContextRegisterStore;
1945        else
1946            context.type = EmulateInstruction::eContextPushRegisterOnStack;
1947        RegisterInfo sp_reg;
1948        RegisterInfo dwarf_reg;
1949
1950        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1951        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1952        context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1953        if (Rt != 15)
1954        {
1955            uint32_t reg_value = ReadCoreReg(Rt, &success);
1956            if (!success)
1957                return false;
1958            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1959                return false;
1960        }
1961        else
1962        {
1963            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1964            if (!success)
1965                return false;
1966            if (!MemUWrite (context, addr, pc, addr_byte_size))
1967                return false;
1968        }
1969
1970
1971        if (wback)
1972        {
1973            context.type = EmulateInstruction::eContextAdjustStackPointer;
1974            context.SetImmediateSigned (addr - sp);
1975            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1976                return false;
1977        }
1978    }
1979    return true;
1980}
1981
1982// Vector Push stores multiple extension registers to the stack.
1983// It also updates SP to point to the start of the stored data.
1984bool
1985EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1986{
1987#if 0
1988    // ARM pseudo code...
1989    if (ConditionPassed())
1990    {
1991        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1992        address = SP - imm32;
1993        SP = SP - imm32;
1994        if single_regs then
1995            for r = 0 to regs-1
1996                MemA[address,4] = S[d+r]; address = address+4;
1997        else
1998            for r = 0 to regs-1
1999                // Store as two word-aligned words in the correct order for current endianness.
2000                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2001                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2002                address = address+8;
2003    }
2004#endif
2005
2006    bool success = false;
2007    bool conditional = false;
2008    if (ConditionPassed(opcode, &conditional))
2009    {
2010        const uint32_t addr_byte_size = GetAddressByteSize();
2011        const addr_t sp = ReadCoreReg (SP_REG, &success);
2012        if (!success)
2013            return false;
2014        bool single_regs;
2015        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2016        uint32_t imm32; // stack offset
2017        uint32_t regs;  // number of registers
2018        switch (encoding) {
2019        case eEncodingT1:
2020        case eEncodingA1:
2021            single_regs = false;
2022            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2023            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2024            // If UInt(imm8) is odd, see "FSTMX".
2025            regs = Bits32(opcode, 7, 0) / 2;
2026            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2027            if (regs == 0 || regs > 16 || (d + regs) > 32)
2028                return false;
2029            break;
2030        case eEncodingT2:
2031        case eEncodingA2:
2032            single_regs = true;
2033            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2034            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2035            regs = Bits32(opcode, 7, 0);
2036            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2037            if (regs == 0 || regs > 16 || (d + regs) > 32)
2038                return false;
2039            break;
2040        default:
2041            return false;
2042        }
2043        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2044        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2045        addr_t sp_offset = imm32;
2046        addr_t addr = sp - sp_offset;
2047        uint32_t i;
2048
2049        EmulateInstruction::Context context;
2050        if (conditional)
2051            context.type = EmulateInstruction::eContextRegisterStore;
2052        else
2053            context.type = EmulateInstruction::eContextPushRegisterOnStack;
2054        RegisterInfo dwarf_reg;
2055        RegisterInfo sp_reg;
2056        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2057        for (i=0; i<regs; ++i)
2058        {
2059            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2060            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2061            // uint64_t to accommodate 64-bit registers.
2062            uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2063            if (!success)
2064                return false;
2065            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2066                return false;
2067            addr += reg_byte_size;
2068        }
2069
2070        context.type = EmulateInstruction::eContextAdjustStackPointer;
2071        context.SetImmediateSigned (-sp_offset);
2072
2073        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2074            return false;
2075    }
2076    return true;
2077}
2078
2079// Vector Pop loads multiple extension registers from the stack.
2080// It also updates SP to point just above the loaded data.
2081bool
2082EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2083{
2084#if 0
2085    // ARM pseudo code...
2086    if (ConditionPassed())
2087    {
2088        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2089        address = SP;
2090        SP = SP + imm32;
2091        if single_regs then
2092            for r = 0 to regs-1
2093                S[d+r] = MemA[address,4]; address = address+4;
2094        else
2095            for r = 0 to regs-1
2096                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2097                // Combine the word-aligned words in the correct order for current endianness.
2098                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2099    }
2100#endif
2101
2102    bool success = false;
2103    bool conditional = false;
2104    if (ConditionPassed(opcode, &conditional))
2105    {
2106        const uint32_t addr_byte_size = GetAddressByteSize();
2107        const addr_t sp = ReadCoreReg (SP_REG, &success);
2108        if (!success)
2109            return false;
2110        bool single_regs;
2111        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2112        uint32_t imm32; // stack offset
2113        uint32_t regs;  // number of registers
2114        switch (encoding) {
2115        case eEncodingT1:
2116        case eEncodingA1:
2117            single_regs = false;
2118            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2119            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2120            // If UInt(imm8) is odd, see "FLDMX".
2121            regs = Bits32(opcode, 7, 0) / 2;
2122            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2123            if (regs == 0 || regs > 16 || (d + regs) > 32)
2124                return false;
2125            break;
2126        case eEncodingT2:
2127        case eEncodingA2:
2128            single_regs = true;
2129            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2130            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2131            regs = Bits32(opcode, 7, 0);
2132            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2133            if (regs == 0 || regs > 16 || (d + regs) > 32)
2134                return false;
2135            break;
2136        default:
2137            return false;
2138        }
2139        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2140        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2141        addr_t sp_offset = imm32;
2142        addr_t addr = sp;
2143        uint32_t i;
2144        uint64_t data; // uint64_t to accomodate 64-bit registers.
2145
2146        EmulateInstruction::Context context;
2147        if (conditional)
2148            context.type = EmulateInstruction::eContextRegisterLoad;
2149        else
2150            context.type = EmulateInstruction::eContextPopRegisterOffStack;
2151        RegisterInfo dwarf_reg;
2152        RegisterInfo sp_reg;
2153        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2154        for (i=0; i<regs; ++i)
2155        {
2156            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2157            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2158            data = MemARead(context, addr, reg_byte_size, 0, &success);
2159            if (!success)
2160                return false;
2161            if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2162                return false;
2163            addr += reg_byte_size;
2164        }
2165
2166        context.type = EmulateInstruction::eContextAdjustStackPointer;
2167        context.SetImmediateSigned (sp_offset);
2168
2169        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2170            return false;
2171    }
2172    return true;
2173}
2174
2175// SVC (previously SWI)
2176bool
2177EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2178{
2179#if 0
2180    // ARM pseudo code...
2181    if (ConditionPassed())
2182    {
2183        EncodingSpecificOperations();
2184        CallSupervisor();
2185    }
2186#endif
2187
2188    bool success = false;
2189
2190    if (ConditionPassed(opcode))
2191    {
2192        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2193        addr_t lr; // next instruction address
2194        if (!success)
2195            return false;
2196        uint32_t imm32; // the immediate constant
2197        uint32_t mode;  // ARM or Thumb mode
2198        switch (encoding) {
2199        case eEncodingT1:
2200            lr = (pc + 2) | 1u; // return address
2201            imm32 = Bits32(opcode, 7, 0);
2202            mode = eModeThumb;
2203            break;
2204        case eEncodingA1:
2205            lr = pc + 4; // return address
2206            imm32 = Bits32(opcode, 23, 0);
2207            mode = eModeARM;
2208            break;
2209        default:
2210            return false;
2211        }
2212
2213        EmulateInstruction::Context context;
2214        context.type = EmulateInstruction::eContextSupervisorCall;
2215        context.SetISAAndImmediate (mode, imm32);
2216        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2217            return false;
2218    }
2219    return true;
2220}
2221
2222// If Then makes up to four following instructions (the IT block) conditional.
2223bool
2224EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2225{
2226#if 0
2227    // ARM pseudo code...
2228    EncodingSpecificOperations();
2229    ITSTATE.IT<7:0> = firstcond:mask;
2230#endif
2231
2232    m_it_session.InitIT(Bits32(opcode, 7, 0));
2233    return true;
2234}
2235
2236bool
2237EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2238{
2239    // NOP, nothing to do...
2240    return true;
2241}
2242
2243// Branch causes a branch to a target address.
2244bool
2245EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2246{
2247#if 0
2248    // ARM pseudo code...
2249    if (ConditionPassed())
2250    {
2251        EncodingSpecificOperations();
2252        BranchWritePC(PC + imm32);
2253    }
2254#endif
2255
2256    bool success = false;
2257
2258    if (ConditionPassed(opcode))
2259    {
2260        EmulateInstruction::Context context;
2261        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2262        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2263        if (!success)
2264            return false;
2265        addr_t target; // target address
2266        int32_t imm32; // PC-relative offset
2267        switch (encoding) {
2268        case eEncodingT1:
2269            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2270            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2271            target = pc + imm32;
2272            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2273            break;
2274        case eEncodingT2:
2275            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2276            target = pc + imm32;
2277            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2278            break;
2279        case eEncodingT3:
2280            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2281            {
2282            uint32_t S = Bit32(opcode, 26);
2283            uint32_t imm6 = Bits32(opcode, 21, 16);
2284            uint32_t J1 = Bit32(opcode, 13);
2285            uint32_t J2 = Bit32(opcode, 11);
2286            uint32_t imm11 = Bits32(opcode, 10, 0);
2287            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2288            imm32 = llvm::SignExtend32<21>(imm21);
2289            target = pc + imm32;
2290            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2291            break;
2292            }
2293        case eEncodingT4:
2294            {
2295            uint32_t S = Bit32(opcode, 26);
2296            uint32_t imm10 = Bits32(opcode, 25, 16);
2297            uint32_t J1 = Bit32(opcode, 13);
2298            uint32_t J2 = Bit32(opcode, 11);
2299            uint32_t imm11 = Bits32(opcode, 10, 0);
2300            uint32_t I1 = !(J1 ^ S);
2301            uint32_t I2 = !(J2 ^ S);
2302            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2303            imm32 = llvm::SignExtend32<25>(imm25);
2304            target = pc + imm32;
2305            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2306            break;
2307            }
2308        case eEncodingA1:
2309            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2310            target = pc + imm32;
2311            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2312            break;
2313        default:
2314            return false;
2315        }
2316        if (!BranchWritePC(context, target))
2317            return false;
2318    }
2319    return true;
2320}
2321
2322// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2323// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2324// CBNZ, CBZ
2325bool
2326EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2327{
2328#if 0
2329    // ARM pseudo code...
2330    EncodingSpecificOperations();
2331    if nonzero ^ IsZero(R[n]) then
2332        BranchWritePC(PC + imm32);
2333#endif
2334
2335    bool success = false;
2336
2337    // Read the register value from the operand register Rn.
2338    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2339    if (!success)
2340        return false;
2341
2342    EmulateInstruction::Context context;
2343    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2344    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2345    if (!success)
2346        return false;
2347
2348    addr_t target;  // target address
2349    uint32_t imm32; // PC-relative offset to branch forward
2350    bool nonzero;
2351    switch (encoding) {
2352    case eEncodingT1:
2353        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2354        nonzero = BitIsSet(opcode, 11);
2355        target = pc + imm32;
2356        context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2357        break;
2358    default:
2359        return false;
2360    }
2361    if (nonzero ^ (reg_val == 0))
2362        if (!BranchWritePC(context, target))
2363            return false;
2364
2365    return true;
2366}
2367
2368// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2369// A base register provides a pointer to the table, and a second register supplies an index into the table.
2370// The branch length is twice the value of the byte returned from the table.
2371//
2372// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2373// A base register provides a pointer to the table, and a second register supplies an index into the table.
2374// The branch length is twice the value of the halfword returned from the table.
2375// TBB, TBH
2376bool
2377EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2378{
2379#if 0
2380    // ARM pseudo code...
2381    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2382    if is_tbh then
2383        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2384    else
2385        halfwords = UInt(MemU[R[n]+R[m], 1]);
2386    BranchWritePC(PC + 2*halfwords);
2387#endif
2388
2389    bool success = false;
2390
2391    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2392    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2393    bool is_tbh;     // true if table branch halfword
2394    switch (encoding) {
2395    case eEncodingT1:
2396        Rn = Bits32(opcode, 19, 16);
2397        Rm = Bits32(opcode, 3, 0);
2398        is_tbh = BitIsSet(opcode, 4);
2399        if (Rn == 13 || BadReg(Rm))
2400            return false;
2401        if (InITBlock() && !LastInITBlock())
2402            return false;
2403        break;
2404    default:
2405        return false;
2406    }
2407
2408    // Read the address of the table from the operand register Rn.
2409    // The PC can be used, in which case the table immediately follows this instruction.
2410    uint32_t base = ReadCoreReg(Rm, &success);
2411    if (!success)
2412        return false;
2413
2414    // the table index
2415    uint32_t index = ReadCoreReg(Rm, &success);
2416    if (!success)
2417        return false;
2418
2419    // the offsetted table address
2420    addr_t addr = base + (is_tbh ? index*2 : index);
2421
2422    // PC-relative offset to branch forward
2423    EmulateInstruction::Context context;
2424    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2425    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2426    if (!success)
2427        return false;
2428
2429    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2430    if (!success)
2431        return false;
2432
2433    // target address
2434    addr_t target = pc + offset;
2435    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2436    context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2437
2438    if (!BranchWritePC(context, target))
2439        return false;
2440
2441    return true;
2442}
2443
2444// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2445// It can optionally update the condition flags based on the result.
2446bool
2447EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2448{
2449#if 0
2450    if ConditionPassed() then
2451        EncodingSpecificOperations();
2452        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2453        R[d] = result;
2454        if setflags then
2455            APSR.N = result<31>;
2456            APSR.Z = IsZeroBit(result);
2457            APSR.C = carry;
2458            APSR.V = overflow;
2459#endif
2460
2461    bool success = false;
2462
2463    if (ConditionPassed(opcode))
2464    {
2465        uint32_t d;
2466        uint32_t n;
2467        bool setflags;
2468        uint32_t imm32;
2469        uint32_t carry_out;
2470
2471        //EncodingSpecificOperations();
2472        switch (encoding)
2473        {
2474            case eEncodingT1:
2475                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2476                d = Bits32 (opcode, 2, 0);
2477                n = Bits32 (opcode, 5, 3);
2478                setflags = !InITBlock();
2479                imm32 = Bits32 (opcode, 8,6);
2480
2481                break;
2482
2483            case eEncodingT2:
2484                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2485                d = Bits32 (opcode, 10, 8);
2486                n = Bits32 (opcode, 10, 8);
2487                setflags = !InITBlock();
2488                imm32 = Bits32 (opcode, 7, 0);
2489
2490                break;
2491
2492            case eEncodingT3:
2493                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2494                // if Rn == '1101' then SEE ADD (SP plus immediate);
2495                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2496                d = Bits32 (opcode, 11, 8);
2497                n = Bits32 (opcode, 19, 16);
2498                setflags = BitIsSet (opcode, 20);
2499                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2500
2501                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2502                if (BadReg (d) || (n == 15))
2503                    return false;
2504
2505                break;
2506
2507            case eEncodingT4:
2508            {
2509                // if Rn == '1111' then SEE ADR;
2510                // if Rn == '1101' then SEE ADD (SP plus immediate);
2511                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2512                d = Bits32 (opcode, 11, 8);
2513                n = Bits32 (opcode, 19, 16);
2514                setflags = false;
2515                uint32_t i = Bit32 (opcode, 26);
2516                uint32_t imm3 = Bits32 (opcode, 14, 12);
2517                uint32_t imm8 = Bits32 (opcode, 7, 0);
2518                imm32 = (i << 11) | (imm3 << 8) | imm8;
2519
2520                // if BadReg(d) then UNPREDICTABLE;
2521                if (BadReg (d))
2522                    return false;
2523
2524                break;
2525            }
2526            default:
2527                return false;
2528        }
2529
2530        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2531        if (!success)
2532            return false;
2533
2534        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2535        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2536
2537        RegisterInfo reg_n;
2538        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2539
2540        EmulateInstruction::Context context;
2541        context.type = eContextArithmetic;
2542        context.SetRegisterPlusOffset (reg_n, imm32);
2543
2544        //R[d] = result;
2545        //if setflags then
2546            //APSR.N = result<31>;
2547            //APSR.Z = IsZeroBit(result);
2548            //APSR.C = carry;
2549            //APSR.V = overflow;
2550        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2551            return false;
2552
2553    }
2554    return true;
2555}
2556
2557// This instruction adds an immediate value to a register value, and writes the result to the destination
2558// register.  It can optionally update the condition flags based on the result.
2559bool
2560EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2561{
2562#if 0
2563    // ARM pseudo code...
2564    if ConditionPassed() then
2565        EncodingSpecificOperations();
2566        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2567        if d == 15 then
2568            ALUWritePC(result); // setflags is always FALSE here
2569        else
2570            R[d] = result;
2571            if setflags then
2572                APSR.N = result<31>;
2573                APSR.Z = IsZeroBit(result);
2574                APSR.C = carry;
2575                APSR.V = overflow;
2576#endif
2577
2578    bool success = false;
2579
2580    if (ConditionPassed(opcode))
2581    {
2582        uint32_t Rd, Rn;
2583        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2584        bool setflags;
2585        switch (encoding)
2586        {
2587        case eEncodingA1:
2588            Rd = Bits32(opcode, 15, 12);
2589            Rn = Bits32(opcode, 19, 16);
2590            setflags = BitIsSet(opcode, 20);
2591            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2592            break;
2593        default:
2594            return false;
2595        }
2596
2597        // Read the first operand.
2598        uint32_t val1 = ReadCoreReg(Rn, &success);
2599        if (!success)
2600            return false;
2601
2602        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2603
2604        EmulateInstruction::Context context;
2605        context.type = eContextArithmetic;
2606        RegisterInfo dwarf_reg;
2607        GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2608        context.SetRegisterPlusOffset (dwarf_reg, imm32);
2609
2610        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2611            return false;
2612    }
2613    return true;
2614}
2615
2616// This instruction adds a register value and an optionally-shifted register value, and writes the result
2617// to the destination register. It can optionally update the condition flags based on the result.
2618bool
2619EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2620{
2621#if 0
2622    // ARM pseudo code...
2623    if ConditionPassed() then
2624        EncodingSpecificOperations();
2625        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2626        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2627        if d == 15 then
2628            ALUWritePC(result); // setflags is always FALSE here
2629        else
2630            R[d] = result;
2631            if setflags then
2632                APSR.N = result<31>;
2633                APSR.Z = IsZeroBit(result);
2634                APSR.C = carry;
2635                APSR.V = overflow;
2636#endif
2637
2638    bool success = false;
2639
2640    if (ConditionPassed(opcode))
2641    {
2642        uint32_t Rd, Rn, Rm;
2643        ARM_ShifterType shift_t;
2644        uint32_t shift_n; // the shift applied to the value read from Rm
2645        bool setflags;
2646        switch (encoding)
2647        {
2648        case eEncodingT1:
2649            Rd = Bits32(opcode, 2, 0);
2650            Rn = Bits32(opcode, 5, 3);
2651            Rm = Bits32(opcode, 8, 6);
2652            setflags = !InITBlock();
2653            shift_t = SRType_LSL;
2654            shift_n = 0;
2655            break;
2656        case eEncodingT2:
2657            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2658            Rm = Bits32(opcode, 6, 3);
2659            setflags = false;
2660            shift_t = SRType_LSL;
2661            shift_n = 0;
2662            if (Rn == 15 && Rm == 15)
2663                return false;
2664            if (Rd == 15 && InITBlock() && !LastInITBlock())
2665                return false;
2666            break;
2667        case eEncodingA1:
2668            Rd = Bits32(opcode, 15, 12);
2669            Rn = Bits32(opcode, 19, 16);
2670            Rm = Bits32(opcode, 3, 0);
2671            setflags = BitIsSet(opcode, 20);
2672            shift_n = DecodeImmShiftARM(opcode, shift_t);
2673            break;
2674        default:
2675            return false;
2676        }
2677
2678        // Read the first operand.
2679        uint32_t val1 = ReadCoreReg(Rn, &success);
2680        if (!success)
2681            return false;
2682
2683        // Read the second operand.
2684        uint32_t val2 = ReadCoreReg(Rm, &success);
2685        if (!success)
2686            return false;
2687
2688        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2689        if (!success)
2690            return false;
2691        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2692
2693        EmulateInstruction::Context context;
2694        context.type = eContextArithmetic;
2695        RegisterInfo op1_reg;
2696        RegisterInfo op2_reg;
2697        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2698        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2699        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2700
2701        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2702            return false;
2703    }
2704    return true;
2705}
2706
2707// Compare Negative (immediate) adds a register value and an immediate value.
2708// It updates the condition flags based on the result, and discards the result.
2709bool
2710EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2711{
2712#if 0
2713    // ARM pseudo code...
2714    if ConditionPassed() then
2715        EncodingSpecificOperations();
2716        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2717        APSR.N = result<31>;
2718        APSR.Z = IsZeroBit(result);
2719        APSR.C = carry;
2720        APSR.V = overflow;
2721#endif
2722
2723    bool success = false;
2724
2725    uint32_t Rn; // the first operand
2726    uint32_t imm32; // the immediate value to be compared with
2727    switch (encoding) {
2728    case eEncodingT1:
2729        Rn = Bits32(opcode, 19, 16);
2730        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2731        if (Rn == 15)
2732            return false;
2733        break;
2734    case eEncodingA1:
2735        Rn = Bits32(opcode, 19, 16);
2736        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2737        break;
2738    default:
2739        return false;
2740    }
2741    // Read the register value from the operand register Rn.
2742    uint32_t reg_val = ReadCoreReg(Rn, &success);
2743    if (!success)
2744        return false;
2745
2746    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2747
2748    EmulateInstruction::Context context;
2749    context.type = EmulateInstruction::eContextImmediate;
2750    context.SetNoArgs ();
2751    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2752        return false;
2753
2754    return true;
2755}
2756
2757// Compare Negative (register) adds a register value and an optionally-shifted register value.
2758// It updates the condition flags based on the result, and discards the result.
2759bool
2760EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2761{
2762#if 0
2763    // ARM pseudo code...
2764    if ConditionPassed() then
2765        EncodingSpecificOperations();
2766        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2767        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2768        APSR.N = result<31>;
2769        APSR.Z = IsZeroBit(result);
2770        APSR.C = carry;
2771        APSR.V = overflow;
2772#endif
2773
2774    bool success = false;
2775
2776    uint32_t Rn; // the first operand
2777    uint32_t Rm; // the second operand
2778    ARM_ShifterType shift_t;
2779    uint32_t shift_n; // the shift applied to the value read from Rm
2780    switch (encoding) {
2781    case eEncodingT1:
2782        Rn = Bits32(opcode, 2, 0);
2783        Rm = Bits32(opcode, 5, 3);
2784        shift_t = SRType_LSL;
2785        shift_n = 0;
2786        break;
2787    case eEncodingT2:
2788        Rn = Bits32(opcode, 19, 16);
2789        Rm = Bits32(opcode, 3, 0);
2790        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2791        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2792        if (Rn == 15 || BadReg(Rm))
2793            return false;
2794        break;
2795    case eEncodingA1:
2796        Rn = Bits32(opcode, 19, 16);
2797        Rm = Bits32(opcode, 3, 0);
2798        shift_n = DecodeImmShiftARM(opcode, shift_t);
2799        break;
2800    default:
2801        return false;
2802    }
2803    // Read the register value from register Rn.
2804    uint32_t val1 = ReadCoreReg(Rn, &success);
2805    if (!success)
2806        return false;
2807
2808    // Read the register value from register Rm.
2809    uint32_t val2 = ReadCoreReg(Rm, &success);
2810    if (!success)
2811        return false;
2812
2813    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2814    if (!success)
2815        return false;
2816    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2817
2818    EmulateInstruction::Context context;
2819    context.type = EmulateInstruction::eContextImmediate;
2820    context.SetNoArgs();
2821    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2822        return false;
2823
2824    return true;
2825}
2826
2827// Compare (immediate) subtracts an immediate value from a register value.
2828// It updates the condition flags based on the result, and discards the result.
2829bool
2830EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2831{
2832#if 0
2833    // ARM pseudo code...
2834    if ConditionPassed() then
2835        EncodingSpecificOperations();
2836        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2837        APSR.N = result<31>;
2838        APSR.Z = IsZeroBit(result);
2839        APSR.C = carry;
2840        APSR.V = overflow;
2841#endif
2842
2843    bool success = false;
2844
2845    uint32_t Rn; // the first operand
2846    uint32_t imm32; // the immediate value to be compared with
2847    switch (encoding) {
2848    case eEncodingT1:
2849        Rn = Bits32(opcode, 10, 8);
2850        imm32 = Bits32(opcode, 7, 0);
2851        break;
2852    case eEncodingT2:
2853        Rn = Bits32(opcode, 19, 16);
2854        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2855        if (Rn == 15)
2856            return false;
2857        break;
2858    case eEncodingA1:
2859        Rn = Bits32(opcode, 19, 16);
2860        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2861        break;
2862    default:
2863        return false;
2864    }
2865    // Read the register value from the operand register Rn.
2866    uint32_t reg_val = ReadCoreReg(Rn, &success);
2867    if (!success)
2868        return false;
2869
2870    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2871
2872    EmulateInstruction::Context context;
2873    context.type = EmulateInstruction::eContextImmediate;
2874    context.SetNoArgs ();
2875    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2876        return false;
2877
2878    return true;
2879}
2880
2881// Compare (register) subtracts an optionally-shifted register value from a register value.
2882// It updates the condition flags based on the result, and discards the result.
2883bool
2884EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2885{
2886#if 0
2887    // ARM pseudo code...
2888    if ConditionPassed() then
2889        EncodingSpecificOperations();
2890        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2891        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2892        APSR.N = result<31>;
2893        APSR.Z = IsZeroBit(result);
2894        APSR.C = carry;
2895        APSR.V = overflow;
2896#endif
2897
2898    bool success = false;
2899
2900    uint32_t Rn; // the first operand
2901    uint32_t Rm; // the second operand
2902    ARM_ShifterType shift_t;
2903    uint32_t shift_n; // the shift applied to the value read from Rm
2904    switch (encoding) {
2905    case eEncodingT1:
2906        Rn = Bits32(opcode, 2, 0);
2907        Rm = Bits32(opcode, 5, 3);
2908        shift_t = SRType_LSL;
2909        shift_n = 0;
2910        break;
2911    case eEncodingT2:
2912        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2913        Rm = Bits32(opcode, 6, 3);
2914        shift_t = SRType_LSL;
2915        shift_n = 0;
2916        if (Rn < 8 && Rm < 8)
2917            return false;
2918        if (Rn == 15 || Rm == 15)
2919            return false;
2920        break;
2921    case eEncodingA1:
2922        Rn = Bits32(opcode, 19, 16);
2923        Rm = Bits32(opcode, 3, 0);
2924        shift_n = DecodeImmShiftARM(opcode, shift_t);
2925        break;
2926    default:
2927        return false;
2928    }
2929    // Read the register value from register Rn.
2930    uint32_t val1 = ReadCoreReg(Rn, &success);
2931    if (!success)
2932        return false;
2933
2934    // Read the register value from register Rm.
2935    uint32_t val2 = ReadCoreReg(Rm, &success);
2936    if (!success)
2937        return false;
2938
2939    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2940    if (!success)
2941        return false;
2942    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2943
2944    EmulateInstruction::Context context;
2945    context.type = EmulateInstruction::eContextImmediate;
2946    context.SetNoArgs();
2947    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2948        return false;
2949
2950    return true;
2951}
2952
2953// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2954// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2955// optionally update the condition flags based on the result.
2956bool
2957EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2958{
2959#if 0
2960    // ARM pseudo code...
2961    if ConditionPassed() then
2962        EncodingSpecificOperations();
2963        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2964        if d == 15 then         // Can only occur for ARM encoding
2965            ALUWritePC(result); // setflags is always FALSE here
2966        else
2967            R[d] = result;
2968            if setflags then
2969                APSR.N = result<31>;
2970                APSR.Z = IsZeroBit(result);
2971                APSR.C = carry;
2972                // APSR.V unchanged
2973#endif
2974
2975    return EmulateShiftImm (opcode, encoding, SRType_ASR);
2976}
2977
2978// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2979// shifting in copies of its sign bit, and writes the result to the destination register.
2980// The variable number of bits is read from the bottom byte of a register. It can optionally update
2981// the condition flags based on the result.
2982bool
2983EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2984{
2985#if 0
2986    // ARM pseudo code...
2987    if ConditionPassed() then
2988        EncodingSpecificOperations();
2989        shift_n = UInt(R[m]<7:0>);
2990        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2991        R[d] = result;
2992        if setflags then
2993            APSR.N = result<31>;
2994            APSR.Z = IsZeroBit(result);
2995            APSR.C = carry;
2996            // APSR.V unchanged
2997#endif
2998
2999    return EmulateShiftReg (opcode, encoding, SRType_ASR);
3000}
3001
3002// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3003// shifting in zeros, and writes the result to the destination register.  It can optionally
3004// update the condition flags based on the result.
3005bool
3006EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3007{
3008#if 0
3009    // ARM pseudo code...
3010    if ConditionPassed() then
3011        EncodingSpecificOperations();
3012        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3013        if d == 15 then         // Can only occur for ARM encoding
3014            ALUWritePC(result); // setflags is always FALSE here
3015        else
3016            R[d] = result;
3017            if setflags then
3018                APSR.N = result<31>;
3019                APSR.Z = IsZeroBit(result);
3020                APSR.C = carry;
3021                // APSR.V unchanged
3022#endif
3023
3024    return EmulateShiftImm (opcode, encoding, SRType_LSL);
3025}
3026
3027// Logical Shift Left (register) shifts a register value left by a variable number of bits,
3028// shifting in zeros, and writes the result to the destination register.  The variable number
3029// of bits is read from the bottom byte of a register. It can optionally update the condition
3030// flags based on the result.
3031bool
3032EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3033{
3034#if 0
3035    // ARM pseudo code...
3036    if ConditionPassed() then
3037        EncodingSpecificOperations();
3038        shift_n = UInt(R[m]<7:0>);
3039        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3040        R[d] = result;
3041        if setflags then
3042            APSR.N = result<31>;
3043            APSR.Z = IsZeroBit(result);
3044            APSR.C = carry;
3045            // APSR.V unchanged
3046#endif
3047
3048    return EmulateShiftReg (opcode, encoding, SRType_LSL);
3049}
3050
3051// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3052// shifting in zeros, and writes the result to the destination register.  It can optionally
3053// update the condition flags based on the result.
3054bool
3055EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3056{
3057#if 0
3058    // ARM pseudo code...
3059    if ConditionPassed() then
3060        EncodingSpecificOperations();
3061        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3062        if d == 15 then         // Can only occur for ARM encoding
3063            ALUWritePC(result); // setflags is always FALSE here
3064        else
3065            R[d] = result;
3066            if setflags then
3067                APSR.N = result<31>;
3068                APSR.Z = IsZeroBit(result);
3069                APSR.C = carry;
3070                // APSR.V unchanged
3071#endif
3072
3073    return EmulateShiftImm (opcode, encoding, SRType_LSR);
3074}
3075
3076// Logical Shift Right (register) shifts a register value right by a variable number of bits,
3077// shifting in zeros, and writes the result to the destination register.  The variable number
3078// of bits is read from the bottom byte of a register. It can optionally update the condition
3079// flags based on the result.
3080bool
3081EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3082{
3083#if 0
3084    // ARM pseudo code...
3085    if ConditionPassed() then
3086        EncodingSpecificOperations();
3087        shift_n = UInt(R[m]<7:0>);
3088        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3089        R[d] = result;
3090        if setflags then
3091            APSR.N = result<31>;
3092            APSR.Z = IsZeroBit(result);
3093            APSR.C = carry;
3094            // APSR.V unchanged
3095#endif
3096
3097    return EmulateShiftReg (opcode, encoding, SRType_LSR);
3098}
3099
3100// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3101// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3102// It can optionally update the condition flags based on the result.
3103bool
3104EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3105{
3106#if 0
3107    // ARM pseudo code...
3108    if ConditionPassed() then
3109        EncodingSpecificOperations();
3110        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3111        if d == 15 then         // Can only occur for ARM encoding
3112            ALUWritePC(result); // setflags is always FALSE here
3113        else
3114            R[d] = result;
3115            if setflags then
3116                APSR.N = result<31>;
3117                APSR.Z = IsZeroBit(result);
3118                APSR.C = carry;
3119                // APSR.V unchanged
3120#endif
3121
3122    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3123}
3124
3125// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3126// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3127// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3128// flags based on the result.
3129bool
3130EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3131{
3132#if 0
3133    // ARM pseudo code...
3134    if ConditionPassed() then
3135        EncodingSpecificOperations();
3136        shift_n = UInt(R[m]<7:0>);
3137        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3138        R[d] = result;
3139        if setflags then
3140            APSR.N = result<31>;
3141            APSR.Z = IsZeroBit(result);
3142            APSR.C = carry;
3143            // APSR.V unchanged
3144#endif
3145
3146    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3147}
3148
3149// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3150// with the carry flag shifted into bit [31].
3151//
3152// RRX can optionally update the condition flags based on the result.
3153// In that case, bit [0] is shifted into the carry flag.
3154bool
3155EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3156{
3157#if 0
3158    // ARM pseudo code...
3159    if ConditionPassed() then
3160        EncodingSpecificOperations();
3161        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3162        if d == 15 then         // Can only occur for ARM encoding
3163            ALUWritePC(result); // setflags is always FALSE here
3164        else
3165            R[d] = result;
3166            if setflags then
3167                APSR.N = result<31>;
3168                APSR.Z = IsZeroBit(result);
3169                APSR.C = carry;
3170                // APSR.V unchanged
3171#endif
3172
3173    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3174}
3175
3176bool
3177EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3178{
3179//    assert(shift_type == SRType_ASR
3180//           || shift_type == SRType_LSL
3181//           || shift_type == SRType_LSR
3182//           || shift_type == SRType_ROR
3183//           || shift_type == SRType_RRX);
3184
3185    bool success = false;
3186
3187    if (ConditionPassed(opcode))
3188    {
3189        uint32_t Rd;    // the destination register
3190        uint32_t Rm;    // the first operand register
3191        uint32_t imm5;  // encoding for the shift amount
3192        uint32_t carry; // the carry bit after the shift operation
3193        bool setflags;
3194
3195        // Special case handling!
3196        // A8.6.139 ROR (immediate) -- Encoding T1
3197        ARMEncoding use_encoding = encoding;
3198        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3199        {
3200            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3201            // have the same decoding of bit fields as the other Thumb2 shift operations.
3202            use_encoding = eEncodingT2;
3203        }
3204
3205        switch (use_encoding) {
3206        case eEncodingT1:
3207            // Due to the above special case handling!
3208            if (shift_type == SRType_ROR)
3209                return false;
3210
3211            Rd = Bits32(opcode, 2, 0);
3212            Rm = Bits32(opcode, 5, 3);
3213            setflags = !InITBlock();
3214            imm5 = Bits32(opcode, 10, 6);
3215            break;
3216        case eEncodingT2:
3217            // A8.6.141 RRX
3218            // There's no imm form of RRX instructions.
3219            if (shift_type == SRType_RRX)
3220                return false;
3221
3222            Rd = Bits32(opcode, 11, 8);
3223            Rm = Bits32(opcode, 3, 0);
3224            setflags = BitIsSet(opcode, 20);
3225            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3226            if (BadReg(Rd) || BadReg(Rm))
3227                return false;
3228            break;
3229        case eEncodingA1:
3230            Rd = Bits32(opcode, 15, 12);
3231            Rm = Bits32(opcode, 3, 0);
3232            setflags = BitIsSet(opcode, 20);
3233            imm5 = Bits32(opcode, 11, 7);
3234            break;
3235        default:
3236            return false;
3237        }
3238
3239        // A8.6.139 ROR (immediate)
3240        if (shift_type == SRType_ROR && imm5 == 0)
3241            shift_type = SRType_RRX;
3242
3243        // Get the first operand.
3244        uint32_t value = ReadCoreReg (Rm, &success);
3245        if (!success)
3246            return false;
3247
3248        // Decode the shift amount if not RRX.
3249        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3250
3251        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3252        if (!success)
3253            return false;
3254
3255        // The context specifies that an immediate is to be moved into Rd.
3256        EmulateInstruction::Context context;
3257        context.type = EmulateInstruction::eContextImmediate;
3258        context.SetNoArgs ();
3259
3260        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3261            return false;
3262    }
3263    return true;
3264}
3265
3266bool
3267EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3268{
3269    // assert(shift_type == SRType_ASR
3270    //        || shift_type == SRType_LSL
3271    //        || shift_type == SRType_LSR
3272    //        || shift_type == SRType_ROR);
3273
3274    bool success = false;
3275
3276    if (ConditionPassed(opcode))
3277    {
3278        uint32_t Rd;    // the destination register
3279        uint32_t Rn;    // the first operand register
3280        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3281        uint32_t carry; // the carry bit after the shift operation
3282        bool setflags;
3283        switch (encoding) {
3284        case eEncodingT1:
3285            Rd = Bits32(opcode, 2, 0);
3286            Rn = Rd;
3287            Rm = Bits32(opcode, 5, 3);
3288            setflags = !InITBlock();
3289            break;
3290        case eEncodingT2:
3291            Rd = Bits32(opcode, 11, 8);
3292            Rn = Bits32(opcode, 19, 16);
3293            Rm = Bits32(opcode, 3, 0);
3294            setflags = BitIsSet(opcode, 20);
3295            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3296                return false;
3297            break;
3298        case eEncodingA1:
3299            Rd = Bits32(opcode, 15, 12);
3300            Rn = Bits32(opcode, 3, 0);
3301            Rm = Bits32(opcode, 11, 8);
3302            setflags = BitIsSet(opcode, 20);
3303            if (Rd == 15 || Rn == 15 || Rm == 15)
3304                return false;
3305            break;
3306        default:
3307            return false;
3308        }
3309
3310        // Get the first operand.
3311        uint32_t value = ReadCoreReg (Rn, &success);
3312        if (!success)
3313            return false;
3314        // Get the Rm register content.
3315        uint32_t val = ReadCoreReg (Rm, &success);
3316        if (!success)
3317            return false;
3318
3319        // Get the shift amount.
3320        uint32_t amt = Bits32(val, 7, 0);
3321
3322        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3323        if (!success)
3324            return false;
3325
3326        // The context specifies that an immediate is to be moved into Rd.
3327        EmulateInstruction::Context context;
3328        context.type = EmulateInstruction::eContextImmediate;
3329        context.SetNoArgs ();
3330
3331        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3332            return false;
3333    }
3334    return true;
3335}
3336
3337// LDM loads multiple registers from consecutive memory locations, using an
3338// address from a base register.  Optionally the address just above the highest of those locations
3339// can be written back to the base register.
3340bool
3341EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3342{
3343#if 0
3344    // ARM pseudo code...
3345    if ConditionPassed()
3346        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3347        address = R[n];
3348
3349        for i = 0 to 14
3350            if registers<i> == '1' then
3351                R[i] = MemA[address, 4]; address = address + 4;
3352        if registers<15> == '1' then
3353            LoadWritePC (MemA[address, 4]);
3354
3355        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3356        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3357
3358#endif
3359
3360    bool success = false;
3361    bool conditional = false;
3362    if (ConditionPassed(opcode, &conditional))
3363    {
3364        uint32_t n;
3365        uint32_t registers = 0;
3366        bool wback;
3367        const uint32_t addr_byte_size = GetAddressByteSize();
3368        switch (encoding)
3369        {
3370            case eEncodingT1:
3371                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3372                n = Bits32 (opcode, 10, 8);
3373                registers = Bits32 (opcode, 7, 0);
3374                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3375                wback = BitIsClear (registers, n);
3376                // if BitCount(registers) < 1 then UNPREDICTABLE;
3377                if (BitCount(registers) < 1)
3378                    return false;
3379                break;
3380            case eEncodingT2:
3381                // if W == '1' && Rn == '1101' then SEE POP;
3382                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3383                n = Bits32 (opcode, 19, 16);
3384                registers = Bits32 (opcode, 15, 0);
3385                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3386                wback = BitIsSet (opcode, 21);
3387
3388                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3389                if ((n == 15)
3390                    || (BitCount (registers) < 2)
3391                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3392                    return false;
3393
3394                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3395                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3396                    return false;
3397
3398                // if wback && registers<n> == '1' then UNPREDICTABLE;
3399                if (wback
3400                    && BitIsSet (registers, n))
3401                    return false;
3402                break;
3403
3404            case eEncodingA1:
3405                n = Bits32 (opcode, 19, 16);
3406                registers = Bits32 (opcode, 15, 0);
3407                wback = BitIsSet (opcode, 21);
3408                if ((n == 15)
3409                    || (BitCount (registers) < 1))
3410                    return false;
3411                break;
3412            default:
3413                return false;
3414        }
3415
3416        int32_t offset = 0;
3417        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3418        if (!success)
3419            return false;
3420
3421        EmulateInstruction::Context context;
3422        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3423        RegisterInfo dwarf_reg;
3424        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3425        context.SetRegisterPlusOffset (dwarf_reg, offset);
3426
3427        for (int i = 0; i < 14; ++i)
3428        {
3429            if (BitIsSet (registers, i))
3430            {
3431                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3432                context.SetRegisterPlusOffset (dwarf_reg, offset);
3433                if (wback && (n == 13)) // Pop Instruction
3434                {
3435                    if (conditional)
3436                        context.type = EmulateInstruction::eContextRegisterLoad;
3437                    else
3438                        context.type = EmulateInstruction::eContextPopRegisterOffStack;
3439                }
3440
3441                // R[i] = MemA [address, 4]; address = address + 4;
3442                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3443                if (!success)
3444                    return false;
3445
3446                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3447                    return false;
3448
3449                offset += addr_byte_size;
3450            }
3451        }
3452
3453        if (BitIsSet (registers, 15))
3454        {
3455            //LoadWritePC (MemA [address, 4]);
3456            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3457            context.SetRegisterPlusOffset (dwarf_reg, offset);
3458            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3459            if (!success)
3460                return false;
3461            // In ARMv5T and above, this is an interworking branch.
3462            if (!LoadWritePC(context, data))
3463                return false;
3464        }
3465
3466        if (wback && BitIsClear (registers, n))
3467        {
3468            // R[n] = R[n] + 4 * BitCount (registers)
3469            int32_t offset = addr_byte_size * BitCount (registers);
3470            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3471            context.SetRegisterPlusOffset (dwarf_reg, offset);
3472
3473            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3474                return false;
3475        }
3476        if (wback && BitIsSet (registers, n))
3477            // R[n] bits(32) UNKNOWN;
3478            return WriteBits32Unknown (n);
3479    }
3480    return true;
3481}
3482
3483// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3484// The consecutive memory locations end at this address and the address just below the lowest of those locations
3485// can optionally be written back to the base register.
3486bool
3487EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3488{
3489#if 0
3490    // ARM pseudo code...
3491    if ConditionPassed() then
3492        EncodingSpecificOperations();
3493        address = R[n] - 4*BitCount(registers) + 4;
3494
3495        for i = 0 to 14
3496            if registers<i> == '1' then
3497                  R[i] = MemA[address,4]; address = address + 4;
3498
3499        if registers<15> == '1' then
3500            LoadWritePC(MemA[address,4]);
3501
3502        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3503        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3504#endif
3505
3506    bool success = false;
3507
3508    if (ConditionPassed(opcode))
3509    {
3510        uint32_t n;
3511        uint32_t registers = 0;
3512        bool wback;
3513        const uint32_t addr_byte_size = GetAddressByteSize();
3514
3515        // EncodingSpecificOperations();
3516        switch (encoding)
3517        {
3518            case eEncodingA1:
3519                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3520                n = Bits32 (opcode, 19, 16);
3521                registers = Bits32 (opcode, 15, 0);
3522                wback = BitIsSet (opcode, 21);
3523
3524                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3525                if ((n == 15) || (BitCount (registers) < 1))
3526                    return false;
3527
3528                break;
3529
3530            default:
3531                return false;
3532        }
3533        // address = R[n] - 4*BitCount(registers) + 4;
3534
3535        int32_t offset = 0;
3536        addr_t Rn = ReadCoreReg (n, &success);
3537
3538        if (!success)
3539            return false;
3540
3541        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3542
3543        EmulateInstruction::Context context;
3544        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3545        RegisterInfo dwarf_reg;
3546        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3547        context.SetRegisterPlusOffset (dwarf_reg, offset);
3548
3549        // for i = 0 to 14
3550        for (int i = 0; i < 14; ++i)
3551        {
3552            // if registers<i> == '1' then
3553            if (BitIsSet (registers, i))
3554            {
3555                  // R[i] = MemA[address,4]; address = address + 4;
3556                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3557                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3558                  if (!success)
3559                      return false;
3560                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3561                      return false;
3562                  offset += addr_byte_size;
3563            }
3564        }
3565
3566        // if registers<15> == '1' then
3567        //     LoadWritePC(MemA[address,4]);
3568        if (BitIsSet (registers, 15))
3569        {
3570            context.SetRegisterPlusOffset (dwarf_reg, offset);
3571            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3572            if (!success)
3573                return false;
3574            // In ARMv5T and above, this is an interworking branch.
3575            if (!LoadWritePC(context, data))
3576                return false;
3577        }
3578
3579        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3580        if (wback && BitIsClear (registers, n))
3581        {
3582            if (!success)
3583                return false;
3584
3585            offset = (addr_byte_size * BitCount (registers)) * -1;
3586            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3587            context.SetImmediateSigned (offset);
3588            addr_t addr = Rn + offset;
3589            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3590                return false;
3591        }
3592
3593        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3594        if (wback && BitIsSet (registers, n))
3595            return WriteBits32Unknown (n);
3596    }
3597    return true;
3598}
3599
3600// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3601// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3602// be optionally written back to the base register.
3603bool
3604EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3605{
3606#if 0
3607    // ARM pseudo code...
3608    if ConditionPassed() then
3609        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3610        address = R[n] - 4*BitCount(registers);
3611
3612        for i = 0 to 14
3613            if registers<i> == '1' then
3614                  R[i] = MemA[address,4]; address = address + 4;
3615        if registers<15> == '1' then
3616                  LoadWritePC(MemA[address,4]);
3617
3618        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3619        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3620#endif
3621
3622    bool success = false;
3623
3624    if (ConditionPassed(opcode))
3625    {
3626        uint32_t n;
3627        uint32_t registers = 0;
3628        bool wback;
3629        const uint32_t addr_byte_size = GetAddressByteSize();
3630        switch (encoding)
3631        {
3632            case eEncodingT1:
3633                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3634                n = Bits32 (opcode, 19, 16);
3635                registers = Bits32 (opcode, 15, 0);
3636                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3637                wback = BitIsSet (opcode, 21);
3638
3639                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3640                if ((n == 15)
3641                    || (BitCount (registers) < 2)
3642                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3643                    return false;
3644
3645                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3646                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3647                    return false;
3648
3649                // if wback && registers<n> == '1' then UNPREDICTABLE;
3650                if (wback && BitIsSet (registers, n))
3651                    return false;
3652
3653                break;
3654
3655            case eEncodingA1:
3656                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3657                n = Bits32 (opcode, 19, 16);
3658                registers = Bits32 (opcode, 15, 0);
3659                wback = BitIsSet (opcode, 21);
3660
3661                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3662                if ((n == 15) || (BitCount (registers) < 1))
3663                    return false;
3664
3665                break;
3666
3667            default:
3668                return false;
3669        }
3670
3671        // address = R[n] - 4*BitCount(registers);
3672
3673        int32_t offset = 0;
3674        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3675
3676        if (!success)
3677            return false;
3678
3679        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3680        EmulateInstruction::Context context;
3681        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3682        RegisterInfo dwarf_reg;
3683        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3684        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3685
3686        for (int i = 0; i < 14; ++i)
3687        {
3688            if (BitIsSet (registers, i))
3689            {
3690                // R[i] = MemA[address,4]; address = address + 4;
3691                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3692                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3693                if (!success)
3694                    return false;
3695
3696                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3697                    return false;
3698
3699                offset += addr_byte_size;
3700            }
3701        }
3702
3703        // if registers<15> == '1' then
3704        //     LoadWritePC(MemA[address,4]);
3705        if (BitIsSet (registers, 15))
3706        {
3707            context.SetRegisterPlusOffset (dwarf_reg, offset);
3708            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3709            if (!success)
3710                return false;
3711            // In ARMv5T and above, this is an interworking branch.
3712            if (!LoadWritePC(context, data))
3713                return false;
3714        }
3715
3716        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3717        if (wback && BitIsClear (registers, n))
3718        {
3719            if (!success)
3720                return false;
3721
3722            offset = (addr_byte_size * BitCount (registers)) * -1;
3723            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3724            context.SetImmediateSigned (offset);
3725            addr_t addr = Rn + offset;
3726            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3727                return false;
3728        }
3729
3730        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3731        if (wback && BitIsSet (registers, n))
3732            return WriteBits32Unknown (n);
3733    }
3734    return true;
3735}
3736
3737// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3738// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3739// optinoally be written back to the base register.
3740bool
3741EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3742{
3743#if 0
3744    if ConditionPassed() then
3745        EncodingSpecificOperations();
3746        address = R[n] + 4;
3747
3748        for i = 0 to 14
3749            if registers<i> == '1' then
3750                  R[i] = MemA[address,4]; address = address + 4;
3751        if registers<15> == '1' then
3752            LoadWritePC(MemA[address,4]);
3753
3754        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3755        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3756#endif
3757
3758    bool success = false;
3759
3760    if (ConditionPassed(opcode))
3761    {
3762        uint32_t n;
3763        uint32_t registers = 0;
3764        bool wback;
3765        const uint32_t addr_byte_size = GetAddressByteSize();
3766        switch (encoding)
3767        {
3768            case eEncodingA1:
3769                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3770                n = Bits32 (opcode, 19, 16);
3771                registers = Bits32 (opcode, 15, 0);
3772                wback = BitIsSet (opcode, 21);
3773
3774                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3775                if ((n == 15) || (BitCount (registers) < 1))
3776                    return false;
3777
3778                break;
3779            default:
3780                return false;
3781        }
3782        // address = R[n] + 4;
3783
3784        int32_t offset = 0;
3785        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3786
3787        if (!success)
3788            return false;
3789
3790        addr_t address = Rn + addr_byte_size;
3791
3792        EmulateInstruction::Context context;
3793        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3794        RegisterInfo dwarf_reg;
3795        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3796        context.SetRegisterPlusOffset (dwarf_reg, offset);
3797
3798        for (int i = 0; i < 14; ++i)
3799        {
3800            if (BitIsSet (registers, i))
3801            {
3802                // R[i] = MemA[address,4]; address = address + 4;
3803
3804                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3805                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3806                if (!success)
3807                    return false;
3808
3809                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3810                    return false;
3811
3812                offset += addr_byte_size;
3813            }
3814        }
3815
3816        // if registers<15> == '1' then
3817        //     LoadWritePC(MemA[address,4]);
3818        if (BitIsSet (registers, 15))
3819        {
3820            context.SetRegisterPlusOffset (dwarf_reg, offset);
3821            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3822            if (!success)
3823                return false;
3824            // In ARMv5T and above, this is an interworking branch.
3825            if (!LoadWritePC(context, data))
3826                return false;
3827        }
3828
3829        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3830        if (wback && BitIsClear (registers, n))
3831        {
3832            if (!success)
3833                return false;
3834
3835            offset = addr_byte_size * BitCount (registers);
3836            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3837            context.SetImmediateSigned (offset);
3838            addr_t addr = Rn + offset;
3839            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3840                return false;
3841        }
3842
3843        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3844        if (wback && BitIsSet (registers, n))
3845            return WriteBits32Unknown (n);
3846    }
3847    return true;
3848}
3849
3850// Load Register (immediate) calculates an address from a base register value and
3851// an immediate offset, loads a word from memory, and writes to a register.
3852// LDR (immediate, Thumb)
3853bool
3854EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3855{
3856#if 0
3857    // ARM pseudo code...
3858    if (ConditionPassed())
3859    {
3860        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3861        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3862        address = if index then offset_addr else R[n];
3863        data = MemU[address,4];
3864        if wback then R[n] = offset_addr;
3865        if t == 15 then
3866            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3867        elsif UnalignedSupport() || address<1:0> = '00' then
3868            R[t] = data;
3869        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3870    }
3871#endif
3872
3873    bool success = false;
3874
3875    if (ConditionPassed(opcode))
3876    {
3877        uint32_t Rt; // the destination register
3878        uint32_t Rn; // the base register
3879        uint32_t imm32; // the immediate offset used to form the address
3880        addr_t offset_addr; // the offset address
3881        addr_t address; // the calculated address
3882        uint32_t data; // the literal data value from memory load
3883        bool add, index, wback;
3884        switch (encoding) {
3885            case eEncodingT1:
3886                Rt = Bits32(opcode, 2, 0);
3887                Rn = Bits32(opcode, 5, 3);
3888                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3889                // index = TRUE; add = TRUE; wback = FALSE
3890                add = true;
3891                index = true;
3892                wback = false;
3893
3894                break;
3895
3896            case eEncodingT2:
3897                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3898                Rt = Bits32 (opcode, 10, 8);
3899                Rn = 13;
3900                imm32 = Bits32 (opcode, 7, 0) << 2;
3901
3902                // index = TRUE; add = TRUE; wback = FALSE;
3903                index = true;
3904                add = true;
3905                wback = false;
3906
3907                break;
3908
3909            case eEncodingT3:
3910                // if Rn == '1111' then SEE LDR (literal);
3911                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3912                Rt = Bits32 (opcode, 15, 12);
3913                Rn = Bits32 (opcode, 19, 16);
3914                imm32 = Bits32 (opcode, 11, 0);
3915
3916                // index = TRUE; add = TRUE; wback = FALSE;
3917                index = true;
3918                add = true;
3919                wback = false;
3920
3921                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3922                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3923                    return false;
3924
3925                break;
3926
3927            case eEncodingT4:
3928                // if Rn == '1111' then SEE LDR (literal);
3929                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3930                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3931                // if P == '0' && W == '0' then UNDEFINED;
3932                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3933                    return false;
3934
3935                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3936                Rt = Bits32 (opcode, 15, 12);
3937                Rn = Bits32 (opcode, 19, 16);
3938                imm32 = Bits32 (opcode, 7, 0);
3939
3940                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3941                index = BitIsSet (opcode, 10);
3942                add = BitIsSet (opcode, 9);
3943                wback = BitIsSet (opcode, 8);
3944
3945                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3946                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3947                    return false;
3948
3949                break;
3950
3951            default:
3952                return false;
3953        }
3954        uint32_t base = ReadCoreReg (Rn, &success);
3955        if (!success)
3956            return false;
3957        if (add)
3958            offset_addr = base + imm32;
3959        else
3960            offset_addr = base - imm32;
3961
3962        address = (index ? offset_addr : base);
3963
3964        RegisterInfo base_reg;
3965        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3966        if (wback)
3967        {
3968            EmulateInstruction::Context ctx;
3969            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3970            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3971
3972            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3973                return false;
3974        }
3975
3976        // Prepare to write to the Rt register.
3977        EmulateInstruction::Context context;
3978        context.type = EmulateInstruction::eContextRegisterLoad;
3979        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3980
3981        // Read memory from the address.
3982        data = MemURead(context, address, 4, 0, &success);
3983        if (!success)
3984            return false;
3985
3986        if (Rt == 15)
3987        {
3988            if (Bits32(address, 1, 0) == 0)
3989            {
3990                if (!LoadWritePC(context, data))
3991                    return false;
3992            }
3993            else
3994                return false;
3995        }
3996        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3997        {
3998            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3999                return false;
4000        }
4001        else
4002            WriteBits32Unknown (Rt);
4003    }
4004    return true;
4005}
4006
4007// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4008// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4009// of those locations can optionally be written back to the base register.
4010bool
4011EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4012{
4013#if 0
4014    if ConditionPassed() then
4015        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4016        address = R[n];
4017
4018        for i = 0 to 14
4019            if registers<i> == '1' then
4020                if i == n && wback && i != LowestSetBit(registers) then
4021                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4022                else
4023                    MemA[address,4] = R[i];
4024                address = address + 4;
4025
4026        if registers<15> == '1' then // Only possible for encoding A1
4027            MemA[address,4] = PCStoreValue();
4028        if wback then R[n] = R[n] + 4*BitCount(registers);
4029#endif
4030
4031    bool success = false;
4032
4033    if (ConditionPassed(opcode))
4034    {
4035        uint32_t n;
4036        uint32_t registers = 0;
4037        bool wback;
4038        const uint32_t addr_byte_size = GetAddressByteSize();
4039
4040        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4041        switch (encoding)
4042        {
4043            case eEncodingT1:
4044                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4045                n = Bits32 (opcode, 10, 8);
4046                registers = Bits32 (opcode, 7, 0);
4047                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4048                wback = true;
4049
4050                // if BitCount(registers) < 1 then UNPREDICTABLE;
4051                if (BitCount (registers) < 1)
4052                    return false;
4053
4054                break;
4055
4056            case eEncodingT2:
4057                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4058                n = Bits32 (opcode, 19, 16);
4059                registers = Bits32 (opcode, 15, 0);
4060                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4061                wback = BitIsSet (opcode, 21);
4062
4063                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4064                if ((n == 15) || (BitCount (registers) < 2))
4065                    return false;
4066
4067                // if wback && registers<n> == '1' then UNPREDICTABLE;
4068                if (wback && BitIsSet (registers, n))
4069                    return false;
4070
4071                break;
4072
4073            case eEncodingA1:
4074                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4075                n = Bits32 (opcode, 19, 16);
4076                registers = Bits32 (opcode, 15, 0);
4077                wback = BitIsSet (opcode, 21);
4078
4079                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4080                if ((n == 15) || (BitCount (registers) < 1))
4081                    return false;
4082
4083                break;
4084
4085            default:
4086                return false;
4087        }
4088
4089        // address = R[n];
4090        int32_t offset = 0;
4091        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4092        if (!success)
4093            return false;
4094
4095        EmulateInstruction::Context context;
4096        context.type = EmulateInstruction::eContextRegisterStore;
4097        RegisterInfo base_reg;
4098        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4099
4100        // for i = 0 to 14
4101        uint32_t lowest_set_bit = 14;
4102        for (uint32_t i = 0; i < 14; ++i)
4103        {
4104            // if registers<i> == '1' then
4105            if (BitIsSet (registers, i))
4106            {
4107                  if (i < lowest_set_bit)
4108                      lowest_set_bit = i;
4109                  // if i == n && wback && i != LowestSetBit(registers) then
4110                  if ((i == n) && wback && (i != lowest_set_bit))
4111                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4112                      WriteBits32UnknownToMemory (address + offset);
4113                  else
4114                  {
4115                     // MemA[address,4] = R[i];
4116                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4117                      if (!success)
4118                          return false;
4119
4120                      RegisterInfo data_reg;
4121                      GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4122                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4123                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
4124                          return false;
4125                  }
4126
4127                  // address = address + 4;
4128                  offset += addr_byte_size;
4129            }
4130        }
4131
4132        // if registers<15> == '1' then // Only possible for encoding A1
4133        //     MemA[address,4] = PCStoreValue();
4134        if (BitIsSet (registers, 15))
4135        {
4136            RegisterInfo pc_reg;
4137            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4138            context.SetRegisterPlusOffset (pc_reg, 8);
4139            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4140            if (!success)
4141                return false;
4142
4143            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4144                return false;
4145        }
4146
4147        // if wback then R[n] = R[n] + 4*BitCount(registers);
4148        if (wback)
4149        {
4150            offset = addr_byte_size * BitCount (registers);
4151            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4152            context.SetImmediateSigned (offset);
4153            addr_t data = address + offset;
4154            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4155                return false;
4156        }
4157    }
4158    return true;
4159}
4160
4161// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4162// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4163// of those locations can optionally be written back to the base register.
4164bool
4165EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4166{
4167#if 0
4168    if ConditionPassed() then
4169        EncodingSpecificOperations();
4170        address = R[n] - 4*BitCount(registers) + 4;
4171
4172        for i = 0 to 14
4173            if registers<i> == '1' then
4174                if i == n && wback && i != LowestSetBit(registers) then
4175                    MemA[address,4] = bits(32) UNKNOWN;
4176                else
4177                    MemA[address,4] = R[i];
4178                address = address + 4;
4179
4180        if registers<15> == '1' then
4181            MemA[address,4] = PCStoreValue();
4182
4183        if wback then R[n] = R[n] - 4*BitCount(registers);
4184#endif
4185
4186    bool success = false;
4187
4188    if (ConditionPassed(opcode))
4189    {
4190        uint32_t n;
4191        uint32_t registers = 0;
4192        bool wback;
4193        const uint32_t addr_byte_size = GetAddressByteSize();
4194
4195        // EncodingSpecificOperations();
4196        switch (encoding)
4197        {
4198            case eEncodingA1:
4199                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4200                n = Bits32 (opcode, 19, 16);
4201                registers = Bits32 (opcode, 15, 0);
4202                wback = BitIsSet (opcode, 21);
4203
4204                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4205                if ((n == 15) || (BitCount (registers) < 1))
4206                    return false;
4207                break;
4208            default:
4209                return false;
4210        }
4211
4212        // address = R[n] - 4*BitCount(registers) + 4;
4213        int32_t offset = 0;
4214        addr_t Rn = ReadCoreReg (n, &success);
4215        if (!success)
4216            return false;
4217
4218        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4219
4220        EmulateInstruction::Context context;
4221        context.type = EmulateInstruction::eContextRegisterStore;
4222        RegisterInfo base_reg;
4223        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4224
4225        // for i = 0 to 14
4226        uint32_t lowest_bit_set = 14;
4227        for (uint32_t i = 0; i < 14; ++i)
4228        {
4229            // if registers<i> == '1' then
4230            if (BitIsSet (registers, i))
4231            {
4232                if (i < lowest_bit_set)
4233                    lowest_bit_set = i;
4234                //if i == n && wback && i != LowestSetBit(registers) then
4235                if ((i == n) && wback && (i != lowest_bit_set))
4236                    // MemA[address,4] = bits(32) UNKNOWN;
4237                    WriteBits32UnknownToMemory (address + offset);
4238                else
4239                {
4240                    // MemA[address,4] = R[i];
4241                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4242                    if (!success)
4243                        return false;
4244
4245                    RegisterInfo data_reg;
4246                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4247                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4248                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4249                        return false;
4250                }
4251
4252                // address = address + 4;
4253                offset += addr_byte_size;
4254            }
4255        }
4256
4257        // if registers<15> == '1' then
4258        //    MemA[address,4] = PCStoreValue();
4259        if (BitIsSet (registers, 15))
4260        {
4261            RegisterInfo pc_reg;
4262            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4263            context.SetRegisterPlusOffset (pc_reg, 8);
4264            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4265            if (!success)
4266                return false;
4267
4268            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4269                return false;
4270        }
4271
4272        // if wback then R[n] = R[n] - 4*BitCount(registers);
4273        if (wback)
4274        {
4275            offset = (addr_byte_size * BitCount (registers)) * -1;
4276            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4277            context.SetImmediateSigned (offset);
4278            addr_t data = Rn + offset;
4279            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4280                return false;
4281        }
4282    }
4283    return true;
4284}
4285
4286// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4287// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4288// those locations can optionally be written back to the base register.
4289bool
4290EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4291{
4292#if 0
4293    if ConditionPassed() then
4294        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4295        address = R[n] - 4*BitCount(registers);
4296
4297        for i = 0 to 14
4298            if registers<i> == '1' then
4299                if i == n && wback && i != LowestSetBit(registers) then
4300                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4301                else
4302                    MemA[address,4] = R[i];
4303                address = address + 4;
4304
4305        if registers<15> == '1' then // Only possible for encoding A1
4306            MemA[address,4] = PCStoreValue();
4307
4308        if wback then R[n] = R[n] - 4*BitCount(registers);
4309#endif
4310
4311
4312    bool success = false;
4313
4314    if (ConditionPassed(opcode))
4315    {
4316        uint32_t n;
4317        uint32_t registers = 0;
4318        bool wback;
4319        const uint32_t addr_byte_size = GetAddressByteSize();
4320
4321        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4322        switch (encoding)
4323        {
4324            case eEncodingT1:
4325                // if W == '1' && Rn == '1101' then SEE PUSH;
4326                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4327                {
4328                    // See PUSH
4329                }
4330                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4331                n = Bits32 (opcode, 19, 16);
4332                registers = Bits32 (opcode, 15, 0);
4333                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4334                wback = BitIsSet (opcode, 21);
4335                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4336                if ((n == 15) || BitCount (registers) < 2)
4337                    return false;
4338                // if wback && registers<n> == '1' then UNPREDICTABLE;
4339                if (wback && BitIsSet (registers, n))
4340                    return false;
4341                break;
4342
4343            case eEncodingA1:
4344                // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4345                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4346                {
4347                    // See Push
4348                }
4349                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4350                n = Bits32 (opcode, 19, 16);
4351                registers = Bits32 (opcode, 15, 0);
4352                wback = BitIsSet (opcode, 21);
4353                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4354                if ((n == 15) || BitCount (registers) < 1)
4355                    return false;
4356                break;
4357
4358            default:
4359                return false;
4360        }
4361
4362        // address = R[n] - 4*BitCount(registers);
4363
4364        int32_t offset = 0;
4365        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4366        if (!success)
4367        return false;
4368
4369        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4370
4371        EmulateInstruction::Context context;
4372        context.type = EmulateInstruction::eContextRegisterStore;
4373        RegisterInfo base_reg;
4374        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4375
4376        // for i = 0 to 14
4377        uint32_t lowest_set_bit = 14;
4378        for (uint32_t i = 0; i < 14; ++i)
4379        {
4380            // if registers<i> == '1' then
4381            if (BitIsSet (registers, i))
4382            {
4383                if (i < lowest_set_bit)
4384                    lowest_set_bit = i;
4385                // if i == n && wback && i != LowestSetBit(registers) then
4386                if ((i == n) && wback && (i != lowest_set_bit))
4387                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4388                    WriteBits32UnknownToMemory (address + offset);
4389                else
4390                {
4391                    // MemA[address,4] = R[i];
4392                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4393                    if (!success)
4394                        return false;
4395
4396                    RegisterInfo data_reg;
4397                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4398                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4399                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4400                        return false;
4401                }
4402
4403                // address = address + 4;
4404                offset += addr_byte_size;
4405            }
4406        }
4407
4408        // if registers<15> == '1' then // Only possible for encoding A1
4409        //     MemA[address,4] = PCStoreValue();
4410        if (BitIsSet (registers, 15))
4411        {
4412            RegisterInfo pc_reg;
4413            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4414            context.SetRegisterPlusOffset (pc_reg, 8);
4415            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4416            if (!success)
4417                return false;
4418
4419            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4420                return false;
4421        }
4422
4423        // if wback then R[n] = R[n] - 4*BitCount(registers);
4424        if (wback)
4425        {
4426            offset = (addr_byte_size * BitCount (registers)) * -1;
4427            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4428            context.SetImmediateSigned (offset);
4429            addr_t data = Rn + offset;
4430            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4431                return false;
4432        }
4433    }
4434    return true;
4435}
4436
4437// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4438// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4439// of those locations can optionally be written back to the base register.
4440bool
4441EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4442{
4443#if 0
4444    if ConditionPassed() then
4445        EncodingSpecificOperations();
4446        address = R[n] + 4;
4447
4448        for i = 0 to 14
4449            if registers<i> == '1' then
4450                if i == n && wback && i != LowestSetBit(registers) then
4451                    MemA[address,4] = bits(32) UNKNOWN;
4452                else
4453                    MemA[address,4] = R[i];
4454                address = address + 4;
4455
4456        if registers<15> == '1' then
4457            MemA[address,4] = PCStoreValue();
4458
4459        if wback then R[n] = R[n] + 4*BitCount(registers);
4460#endif
4461
4462    bool success = false;
4463
4464    if (ConditionPassed(opcode))
4465    {
4466        uint32_t n;
4467        uint32_t registers = 0;
4468        bool wback;
4469        const uint32_t addr_byte_size = GetAddressByteSize();
4470
4471        // EncodingSpecificOperations();
4472        switch (encoding)
4473        {
4474            case eEncodingA1:
4475                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4476                n = Bits32 (opcode, 19, 16);
4477                registers = Bits32 (opcode, 15, 0);
4478                wback = BitIsSet (opcode, 21);
4479
4480                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4481                if ((n == 15) && (BitCount (registers) < 1))
4482                    return false;
4483                break;
4484            default:
4485                return false;
4486        }
4487        // address = R[n] + 4;
4488
4489        int32_t offset = 0;
4490        addr_t Rn = ReadCoreReg (n, &success);
4491        if (!success)
4492            return false;
4493
4494        addr_t address = Rn + addr_byte_size;
4495
4496        EmulateInstruction::Context context;
4497        context.type = EmulateInstruction::eContextRegisterStore;
4498        RegisterInfo base_reg;
4499        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4500
4501        uint32_t lowest_set_bit = 14;
4502        // for i = 0 to 14
4503        for (uint32_t i = 0; i < 14; ++i)
4504        {
4505            // if registers<i> == '1' then
4506            if (BitIsSet (registers, i))
4507            {
4508                if (i < lowest_set_bit)
4509                    lowest_set_bit = i;
4510                // if i == n && wback && i != LowestSetBit(registers) then
4511                if ((i == n) && wback && (i != lowest_set_bit))
4512                    // MemA[address,4] = bits(32) UNKNOWN;
4513                    WriteBits32UnknownToMemory (address + offset);
4514                // else
4515                else
4516                {
4517                    // MemA[address,4] = R[i];
4518                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4519                    if (!success)
4520                        return false;
4521
4522                    RegisterInfo data_reg;
4523                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4524                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4525                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4526                        return false;
4527                }
4528
4529                // address = address + 4;
4530                offset += addr_byte_size;
4531            }
4532        }
4533
4534        // if registers<15> == '1' then
4535            // MemA[address,4] = PCStoreValue();
4536        if (BitIsSet (registers, 15))
4537        {
4538            RegisterInfo pc_reg;
4539            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4540            context.SetRegisterPlusOffset (pc_reg, 8);
4541            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4542            if (!success)
4543            return false;
4544
4545            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4546                return false;
4547        }
4548
4549        // if wback then R[n] = R[n] + 4*BitCount(registers);
4550        if (wback)
4551        {
4552            offset = addr_byte_size * BitCount (registers);
4553            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4554            context.SetImmediateSigned (offset);
4555            addr_t data = Rn + offset;
4556            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4557                return false;
4558        }
4559    }
4560    return true;
4561}
4562
4563// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4564// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4565bool
4566EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4567{
4568#if 0
4569    if ConditionPassed() then
4570        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4571        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4572        address = if index then offset_addr else R[n];
4573        if UnalignedSupport() || address<1:0> == '00' then
4574            MemU[address,4] = R[t];
4575        else // Can only occur before ARMv7
4576            MemU[address,4] = bits(32) UNKNOWN;
4577        if wback then R[n] = offset_addr;
4578#endif
4579
4580    bool success = false;
4581
4582    if (ConditionPassed(opcode))
4583    {
4584        const uint32_t addr_byte_size = GetAddressByteSize();
4585
4586        uint32_t t;
4587        uint32_t n;
4588        uint32_t imm32;
4589        bool index;
4590        bool add;
4591        bool wback;
4592        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4593        switch (encoding)
4594        {
4595            case eEncodingT1:
4596                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4597                t = Bits32 (opcode, 2, 0);
4598                n = Bits32 (opcode, 5, 3);
4599                imm32 = Bits32 (opcode, 10, 6) << 2;
4600
4601                // index = TRUE; add = TRUE; wback = FALSE;
4602                index = true;
4603                add = false;
4604                wback = false;
4605                break;
4606
4607            case eEncodingT2:
4608                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4609                t = Bits32 (opcode, 10, 8);
4610                n = 13;
4611                imm32 = Bits32 (opcode, 7, 0) << 2;
4612
4613                // index = TRUE; add = TRUE; wback = FALSE;
4614                index = true;
4615                add = true;
4616                wback = false;
4617                break;
4618
4619            case eEncodingT3:
4620                // if Rn == '1111' then UNDEFINED;
4621                if (Bits32 (opcode, 19, 16) == 15)
4622                    return false;
4623
4624                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4625                t = Bits32 (opcode, 15, 12);
4626                n = Bits32 (opcode, 19, 16);
4627                imm32 = Bits32 (opcode, 11, 0);
4628
4629                // index = TRUE; add = TRUE; wback = FALSE;
4630                index = true;
4631                add = true;
4632                wback = false;
4633
4634                // if t == 15 then UNPREDICTABLE;
4635                if (t == 15)
4636                    return false;
4637                break;
4638
4639            case eEncodingT4:
4640                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4641                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4642                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4643                if ((Bits32 (opcode, 19, 16) == 15)
4644                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4645                    return false;
4646
4647                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4648                t = Bits32 (opcode, 15, 12);
4649                n = Bits32 (opcode, 19, 16);
4650                imm32 = Bits32 (opcode, 7, 0);
4651
4652                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4653                index = BitIsSet (opcode, 10);
4654                add = BitIsSet (opcode, 9);
4655                wback = BitIsSet (opcode, 8);
4656
4657                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4658                if ((t == 15) || (wback && (n == t)))
4659                    return false;
4660                break;
4661
4662            default:
4663                return false;
4664        }
4665
4666        addr_t offset_addr;
4667        addr_t address;
4668
4669        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4670        uint32_t base_address = ReadCoreReg (n, &success);
4671        if (!success)
4672            return false;
4673
4674        if (add)
4675            offset_addr = base_address + imm32;
4676        else
4677            offset_addr = base_address - imm32;
4678
4679        // address = if index then offset_addr else R[n];
4680        if (index)
4681            address = offset_addr;
4682        else
4683            address = base_address;
4684
4685        EmulateInstruction::Context context;
4686        context.type = eContextRegisterStore;
4687        RegisterInfo base_reg;
4688        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4689
4690        // if UnalignedSupport() || address<1:0> == '00' then
4691        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4692        {
4693            // MemU[address,4] = R[t];
4694            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4695            if (!success)
4696                return false;
4697
4698            RegisterInfo data_reg;
4699            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4700            int32_t offset = address - base_address;
4701            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4702            if (!MemUWrite (context, address, data, addr_byte_size))
4703                return false;
4704        }
4705        else
4706        {
4707            // MemU[address,4] = bits(32) UNKNOWN;
4708            WriteBits32UnknownToMemory (address);
4709        }
4710
4711        // if wback then R[n] = offset_addr;
4712        if (wback)
4713        {
4714            context.type = eContextRegisterLoad;
4715            context.SetAddress (offset_addr);
4716            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4717                return false;
4718        }
4719    }
4720    return true;
4721}
4722
4723// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4724// word from a register to memory.   The offset register value can optionally be shifted.
4725bool
4726EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4727{
4728#if 0
4729    if ConditionPassed() then
4730        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4731        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4732        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4733        address = if index then offset_addr else R[n];
4734        if t == 15 then // Only possible for encoding A1
4735            data = PCStoreValue();
4736        else
4737            data = R[t];
4738        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4739            MemU[address,4] = data;
4740        else // Can only occur before ARMv7
4741            MemU[address,4] = bits(32) UNKNOWN;
4742        if wback then R[n] = offset_addr;
4743#endif
4744
4745    bool success = false;
4746
4747    if (ConditionPassed(opcode))
4748    {
4749        const uint32_t addr_byte_size = GetAddressByteSize();
4750
4751        uint32_t t;
4752        uint32_t n;
4753        uint32_t m;
4754        ARM_ShifterType shift_t;
4755        uint32_t shift_n;
4756        bool index;
4757        bool add;
4758        bool wback;
4759
4760        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4761        switch (encoding)
4762        {
4763            case eEncodingT1:
4764                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4765                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4766                t = Bits32 (opcode, 2, 0);
4767                n = Bits32 (opcode, 5, 3);
4768                m = Bits32 (opcode, 8, 6);
4769
4770                // index = TRUE; add = TRUE; wback = FALSE;
4771                index = true;
4772                add = true;
4773                wback = false;
4774
4775                // (shift_t, shift_n) = (SRType_LSL, 0);
4776                shift_t = SRType_LSL;
4777                shift_n = 0;
4778                break;
4779
4780            case eEncodingT2:
4781                // if Rn == '1111' then UNDEFINED;
4782                if (Bits32 (opcode, 19, 16) == 15)
4783                    return false;
4784
4785                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4786                t = Bits32 (opcode, 15, 12);
4787                n = Bits32 (opcode, 19, 16);
4788                m = Bits32 (opcode, 3, 0);
4789
4790                // index = TRUE; add = TRUE; wback = FALSE;
4791                index = true;
4792                add = true;
4793                wback = false;
4794
4795                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4796                shift_t = SRType_LSL;
4797                shift_n = Bits32 (opcode, 5, 4);
4798
4799                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4800                if ((t == 15) || (BadReg (m)))
4801                    return false;
4802                break;
4803
4804            case eEncodingA1:
4805            {
4806                // if P == '0' && W == '1' then SEE STRT;
4807                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4808                t = Bits32 (opcode, 15, 12);
4809                n = Bits32 (opcode, 19, 16);
4810                m = Bits32 (opcode, 3, 0);
4811
4812                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4813                index = BitIsSet (opcode, 24);
4814                add = BitIsSet (opcode, 23);
4815                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4816
4817                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4818                uint32_t typ = Bits32 (opcode, 6, 5);
4819                uint32_t imm5 = Bits32 (opcode, 11, 7);
4820                shift_n = DecodeImmShift(typ, imm5, shift_t);
4821
4822                // if m == 15 then UNPREDICTABLE;
4823                if (m == 15)
4824                    return false;
4825
4826                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4827                if (wback && ((n == 15) || (n == t)))
4828                    return false;
4829
4830                break;
4831            }
4832            default:
4833                return false;
4834        }
4835
4836        addr_t offset_addr;
4837        addr_t address;
4838        int32_t offset = 0;
4839
4840        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4841        if (!success)
4842            return false;
4843
4844        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4845        if (!success)
4846            return false;
4847
4848        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4849        offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4850        if (!success)
4851            return false;
4852
4853        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4854        if (add)
4855            offset_addr = base_address + offset;
4856        else
4857            offset_addr = base_address - offset;
4858
4859        // address = if index then offset_addr else R[n];
4860        if (index)
4861            address = offset_addr;
4862        else
4863            address = base_address;
4864
4865        uint32_t data;
4866        // if t == 15 then // Only possible for encoding A1
4867        if (t == 15)
4868            // data = PCStoreValue();
4869            data = ReadCoreReg (PC_REG, &success);
4870        else
4871            // data = R[t];
4872            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4873
4874        if (!success)
4875            return false;
4876
4877        EmulateInstruction::Context context;
4878        context.type = eContextRegisterStore;
4879
4880        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4881        if (UnalignedSupport ()
4882            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4883            || CurrentInstrSet() == eModeARM)
4884        {
4885            // MemU[address,4] = data;
4886
4887            RegisterInfo base_reg;
4888            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4889
4890            RegisterInfo data_reg;
4891            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4892
4893            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4894            if (!MemUWrite (context, address, data, addr_byte_size))
4895                return false;
4896
4897        }
4898        else
4899            // MemU[address,4] = bits(32) UNKNOWN;
4900            WriteBits32UnknownToMemory (address);
4901
4902        // if wback then R[n] = offset_addr;
4903        if (wback)
4904        {
4905            context.type = eContextRegisterLoad;
4906            context.SetAddress (offset_addr);
4907            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4908                return false;
4909        }
4910
4911    }
4912    return true;
4913}
4914
4915bool
4916EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4917{
4918#if 0
4919    if ConditionPassed() then
4920        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4921        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4922        address = if index then offset_addr else R[n];
4923        MemU[address,1] = R[t]<7:0>;
4924        if wback then R[n] = offset_addr;
4925#endif
4926
4927
4928    bool success = false;
4929
4930    if (ConditionPassed(opcode))
4931    {
4932        uint32_t t;
4933        uint32_t n;
4934        uint32_t imm32;
4935        bool index;
4936        bool add;
4937        bool wback;
4938        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4939        switch (encoding)
4940        {
4941            case eEncodingT1:
4942                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4943                t = Bits32 (opcode, 2, 0);
4944                n = Bits32 (opcode, 5, 3);
4945                imm32 = Bits32 (opcode, 10, 6);
4946
4947                // index = TRUE; add = TRUE; wback = FALSE;
4948                index = true;
4949                add = true;
4950                wback = false;
4951                break;
4952
4953            case eEncodingT2:
4954                // if Rn == '1111' then UNDEFINED;
4955                if (Bits32 (opcode, 19, 16) == 15)
4956                    return false;
4957
4958                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4959                t = Bits32 (opcode, 15, 12);
4960                n = Bits32 (opcode, 19, 16);
4961                imm32 = Bits32 (opcode, 11, 0);
4962
4963                // index = TRUE; add = TRUE; wback = FALSE;
4964                index = true;
4965                add = true;
4966                wback = false;
4967
4968                // if BadReg(t) then UNPREDICTABLE;
4969                if (BadReg (t))
4970                    return false;
4971                break;
4972
4973            case eEncodingT3:
4974                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4975                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4976                if (Bits32 (opcode, 19, 16) == 15)
4977                    return false;
4978
4979                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4980                t = Bits32 (opcode, 15, 12);
4981                n = Bits32 (opcode, 19, 16);
4982                imm32 = Bits32 (opcode, 7, 0);
4983
4984                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4985                index = BitIsSet (opcode, 10);
4986                add = BitIsSet (opcode, 9);
4987                wback = BitIsSet (opcode, 8);
4988
4989                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4990                if ((BadReg (t)) || (wback && (n == t)))
4991                    return false;
4992                break;
4993
4994            default:
4995                return false;
4996        }
4997
4998        addr_t offset_addr;
4999        addr_t address;
5000        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5001        if (!success)
5002            return false;
5003
5004        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5005        if (add)
5006            offset_addr = base_address + imm32;
5007        else
5008            offset_addr = base_address - imm32;
5009
5010        // address = if index then offset_addr else R[n];
5011        if (index)
5012            address = offset_addr;
5013        else
5014            address = base_address;
5015
5016        // MemU[address,1] = R[t]<7:0>
5017        RegisterInfo base_reg;
5018        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5019
5020        RegisterInfo data_reg;
5021        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5022
5023        EmulateInstruction::Context context;
5024        context.type = eContextRegisterStore;
5025        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5026
5027        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5028        if (!success)
5029            return false;
5030
5031        data = Bits32 (data, 7, 0);
5032
5033        if (!MemUWrite (context, address, data, 1))
5034            return false;
5035
5036        // if wback then R[n] = offset_addr;
5037        if (wback)
5038        {
5039            context.type = eContextRegisterLoad;
5040            context.SetAddress (offset_addr);
5041            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5042                return false;
5043        }
5044
5045    }
5046
5047    return true;
5048}
5049
5050// STRH (register) calculates an address from a base register value and an offset register value, and stores a
5051// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5052bool
5053EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5054{
5055#if 0
5056    if ConditionPassed() then
5057        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5058        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5059        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5060        address = if index then offset_addr else R[n];
5061        if UnalignedSupport() || address<0> == '0' then
5062            MemU[address,2] = R[t]<15:0>;
5063        else // Can only occur before ARMv7
5064            MemU[address,2] = bits(16) UNKNOWN;
5065        if wback then R[n] = offset_addr;
5066#endif
5067
5068    bool success = false;
5069
5070    if (ConditionPassed(opcode))
5071    {
5072        uint32_t t;
5073        uint32_t n;
5074        uint32_t m;
5075        bool index;
5076        bool add;
5077        bool wback;
5078        ARM_ShifterType shift_t;
5079        uint32_t shift_n;
5080
5081        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5082        switch (encoding)
5083        {
5084            case eEncodingT1:
5085                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5086                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5087                t = Bits32 (opcode, 2, 0);
5088                n = Bits32 (opcode, 5, 3);
5089                m = Bits32 (opcode, 8, 6);
5090
5091                // index = TRUE; add = TRUE; wback = FALSE;
5092                index = true;
5093                add = true;
5094                wback = false;
5095
5096                // (shift_t, shift_n) = (SRType_LSL, 0);
5097                shift_t = SRType_LSL;
5098                shift_n = 0;
5099
5100                break;
5101
5102            case eEncodingT2:
5103                // if Rn == '1111' then UNDEFINED;
5104                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5105                t = Bits32 (opcode, 15, 12);
5106                n = Bits32 (opcode, 19, 16);
5107                m = Bits32 (opcode, 3, 0);
5108                if (n == 15)
5109                    return false;
5110
5111                // index = TRUE; add = TRUE; wback = FALSE;
5112                index = true;
5113                add = true;
5114                wback = false;
5115
5116                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5117                shift_t = SRType_LSL;
5118                shift_n = Bits32 (opcode, 5, 4);
5119
5120                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5121                if (BadReg (t) || BadReg (m))
5122                    return false;
5123
5124                break;
5125
5126            case eEncodingA1:
5127                // if P == '0' && W == '1' then SEE STRHT;
5128                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5129                t = Bits32 (opcode, 15, 12);
5130                n = Bits32 (opcode, 19, 16);
5131                m = Bits32 (opcode, 3, 0);
5132
5133                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5134                index = BitIsSet (opcode, 24);
5135                add = BitIsSet (opcode, 23);
5136                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5137
5138                // (shift_t, shift_n) = (SRType_LSL, 0);
5139                shift_t = SRType_LSL;
5140                shift_n = 0;
5141
5142                // if t == 15 || m == 15 then UNPREDICTABLE;
5143                if ((t == 15) || (m == 15))
5144                    return false;
5145
5146                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5147                if (wback && ((n == 15) || (n == t)))
5148                    return false;
5149
5150                break;
5151
5152            default:
5153                return false;
5154        }
5155
5156        uint32_t Rm = ReadCoreReg (m, &success);
5157        if (!success)
5158            return false;
5159
5160        uint32_t Rn = ReadCoreReg (n, &success);
5161        if (!success)
5162            return false;
5163
5164        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5165        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5166        if (!success)
5167            return false;
5168
5169        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5170        addr_t offset_addr;
5171        if (add)
5172            offset_addr = Rn + offset;
5173        else
5174            offset_addr = Rn - offset;
5175
5176        // address = if index then offset_addr else R[n];
5177        addr_t address;
5178        if (index)
5179            address = offset_addr;
5180        else
5181            address = Rn;
5182
5183        EmulateInstruction::Context context;
5184        context.type = eContextRegisterStore;
5185        RegisterInfo base_reg;
5186        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5187        RegisterInfo offset_reg;
5188        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5189
5190        // if UnalignedSupport() || address<0> == '0' then
5191        if (UnalignedSupport() || BitIsClear (address, 0))
5192        {
5193            // MemU[address,2] = R[t]<15:0>;
5194            uint32_t Rt = ReadCoreReg (t, &success);
5195            if (!success)
5196                return false;
5197
5198            EmulateInstruction::Context context;
5199            context.type = eContextRegisterStore;
5200            RegisterInfo base_reg;
5201            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5202            RegisterInfo offset_reg;
5203            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5204            RegisterInfo data_reg;
5205            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5206            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5207
5208            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5209                return false;
5210        }
5211        else // Can only occur before ARMv7
5212        {
5213            // MemU[address,2] = bits(16) UNKNOWN;
5214        }
5215
5216        // if wback then R[n] = offset_addr;
5217        if (wback)
5218        {
5219            context.type = eContextAdjustBaseRegister;
5220            context.SetAddress (offset_addr);
5221            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5222                return false;
5223        }
5224    }
5225
5226    return true;
5227}
5228
5229// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5230// and writes the result to the destination register.  It can optionally update the condition flags
5231// based on the result.
5232bool
5233EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5234{
5235#if 0
5236    // ARM pseudo code...
5237    if ConditionPassed() then
5238        EncodingSpecificOperations();
5239        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5240        if d == 15 then         // Can only occur for ARM encoding
5241            ALUWritePC(result); // setflags is always FALSE here
5242        else
5243            R[d] = result;
5244            if setflags then
5245                APSR.N = result<31>;
5246                APSR.Z = IsZeroBit(result);
5247                APSR.C = carry;
5248                APSR.V = overflow;
5249#endif
5250
5251    bool success = false;
5252
5253    if (ConditionPassed(opcode))
5254    {
5255        uint32_t Rd, Rn;
5256        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5257        bool setflags;
5258        switch (encoding)
5259        {
5260        case eEncodingT1:
5261            Rd = Bits32(opcode, 11, 8);
5262            Rn = Bits32(opcode, 19, 16);
5263            setflags = BitIsSet(opcode, 20);
5264            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5265            if (BadReg(Rd) || BadReg(Rn))
5266                return false;
5267            break;
5268        case eEncodingA1:
5269            Rd = Bits32(opcode, 15, 12);
5270            Rn = Bits32(opcode, 19, 16);
5271            setflags = BitIsSet(opcode, 20);
5272            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5273
5274            if (Rd == 15 && setflags)
5275                return EmulateSUBSPcLrEtc (opcode, encoding);
5276            break;
5277        default:
5278            return false;
5279        }
5280
5281        // Read the first operand.
5282        int32_t val1 = ReadCoreReg(Rn, &success);
5283        if (!success)
5284            return false;
5285
5286        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5287
5288        EmulateInstruction::Context context;
5289        context.type = EmulateInstruction::eContextImmediate;
5290        context.SetNoArgs ();
5291
5292        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5293            return false;
5294    }
5295    return true;
5296}
5297
5298// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5299// register value, and writes the result to the destination register.  It can optionally update the
5300// condition flags based on the result.
5301bool
5302EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5303{
5304#if 0
5305    // ARM pseudo code...
5306    if ConditionPassed() then
5307        EncodingSpecificOperations();
5308        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5309        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5310        if d == 15 then         // Can only occur for ARM encoding
5311            ALUWritePC(result); // setflags is always FALSE here
5312        else
5313            R[d] = result;
5314            if setflags then
5315                APSR.N = result<31>;
5316                APSR.Z = IsZeroBit(result);
5317                APSR.C = carry;
5318                APSR.V = overflow;
5319#endif
5320
5321    bool success = false;
5322
5323    if (ConditionPassed(opcode))
5324    {
5325        uint32_t Rd, Rn, Rm;
5326        ARM_ShifterType shift_t;
5327        uint32_t shift_n; // the shift applied to the value read from Rm
5328        bool setflags;
5329        switch (encoding)
5330        {
5331        case eEncodingT1:
5332            Rd = Rn = Bits32(opcode, 2, 0);
5333            Rm = Bits32(opcode, 5, 3);
5334            setflags = !InITBlock();
5335            shift_t = SRType_LSL;
5336            shift_n = 0;
5337            break;
5338        case eEncodingT2:
5339            Rd = Bits32(opcode, 11, 8);
5340            Rn = Bits32(opcode, 19, 16);
5341            Rm = Bits32(opcode, 3, 0);
5342            setflags = BitIsSet(opcode, 20);
5343            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5344            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5345                return false;
5346            break;
5347        case eEncodingA1:
5348            Rd = Bits32(opcode, 15, 12);
5349            Rn = Bits32(opcode, 19, 16);
5350            Rm = Bits32(opcode, 3, 0);
5351            setflags = BitIsSet(opcode, 20);
5352            shift_n = DecodeImmShiftARM(opcode, shift_t);
5353
5354            if (Rd == 15 && setflags)
5355                return EmulateSUBSPcLrEtc (opcode, encoding);
5356            break;
5357        default:
5358            return false;
5359        }
5360
5361        // Read the first operand.
5362        int32_t val1 = ReadCoreReg(Rn, &success);
5363        if (!success)
5364            return false;
5365
5366        // Read the second operand.
5367        int32_t val2 = ReadCoreReg(Rm, &success);
5368        if (!success)
5369            return false;
5370
5371        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5372        if (!success)
5373            return false;
5374        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5375
5376        EmulateInstruction::Context context;
5377        context.type = EmulateInstruction::eContextImmediate;
5378        context.SetNoArgs ();
5379
5380        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5381            return false;
5382    }
5383    return true;
5384}
5385
5386// This instruction adds an immediate value to the PC value to form a PC-relative address,
5387// and writes the result to the destination register.
5388bool
5389EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5390{
5391#if 0
5392    // ARM pseudo code...
5393    if ConditionPassed() then
5394        EncodingSpecificOperations();
5395        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5396        if d == 15 then         // Can only occur for ARM encodings
5397            ALUWritePC(result);
5398        else
5399            R[d] = result;
5400#endif
5401
5402    bool success = false;
5403
5404    if (ConditionPassed(opcode))
5405    {
5406        uint32_t Rd;
5407        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5408        bool add;
5409        switch (encoding)
5410        {
5411        case eEncodingT1:
5412            Rd = Bits32(opcode, 10, 8);
5413            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5414            add = true;
5415            break;
5416        case eEncodingT2:
5417        case eEncodingT3:
5418            Rd = Bits32(opcode, 11, 8);
5419            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5420            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5421            if (BadReg(Rd))
5422                return false;
5423            break;
5424        case eEncodingA1:
5425        case eEncodingA2:
5426            Rd = Bits32(opcode, 15, 12);
5427            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5428            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5429            break;
5430        default:
5431            return false;
5432        }
5433
5434        // Read the PC value.
5435        uint32_t pc = ReadCoreReg(PC_REG, &success);
5436        if (!success)
5437            return false;
5438
5439        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5440
5441        EmulateInstruction::Context context;
5442        context.type = EmulateInstruction::eContextImmediate;
5443        context.SetNoArgs ();
5444
5445        if (!WriteCoreReg(context, result, Rd))
5446            return false;
5447    }
5448    return true;
5449}
5450
5451// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5452// to the destination register.  It can optionally update the condition flags based on the result.
5453bool
5454EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5455{
5456#if 0
5457    // ARM pseudo code...
5458    if ConditionPassed() then
5459        EncodingSpecificOperations();
5460        result = R[n] AND imm32;
5461        if d == 15 then         // Can only occur for ARM encoding
5462            ALUWritePC(result); // setflags is always FALSE here
5463        else
5464            R[d] = result;
5465            if setflags then
5466                APSR.N = result<31>;
5467                APSR.Z = IsZeroBit(result);
5468                APSR.C = carry;
5469                // APSR.V unchanged
5470#endif
5471
5472    bool success = false;
5473
5474    if (ConditionPassed(opcode))
5475    {
5476        uint32_t Rd, Rn;
5477        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5478        bool setflags;
5479        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5480        switch (encoding)
5481        {
5482        case eEncodingT1:
5483            Rd = Bits32(opcode, 11, 8);
5484            Rn = Bits32(opcode, 19, 16);
5485            setflags = BitIsSet(opcode, 20);
5486            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5487            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5488            if (Rd == 15 && setflags)
5489                return EmulateTSTImm(opcode, eEncodingT1);
5490            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5491                return false;
5492            break;
5493        case eEncodingA1:
5494            Rd = Bits32(opcode, 15, 12);
5495            Rn = Bits32(opcode, 19, 16);
5496            setflags = BitIsSet(opcode, 20);
5497            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5498
5499            if (Rd == 15 && setflags)
5500                return EmulateSUBSPcLrEtc (opcode, encoding);
5501            break;
5502        default:
5503            return false;
5504        }
5505
5506        // Read the first operand.
5507        uint32_t val1 = ReadCoreReg(Rn, &success);
5508        if (!success)
5509            return false;
5510
5511        uint32_t result = val1 & imm32;
5512
5513        EmulateInstruction::Context context;
5514        context.type = EmulateInstruction::eContextImmediate;
5515        context.SetNoArgs ();
5516
5517        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5518            return false;
5519    }
5520    return true;
5521}
5522
5523// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5524// and writes the result to the destination register.  It can optionally update the condition flags
5525// based on the result.
5526bool
5527EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5528{
5529#if 0
5530    // ARM pseudo code...
5531    if ConditionPassed() then
5532        EncodingSpecificOperations();
5533        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5534        result = R[n] AND shifted;
5535        if d == 15 then         // Can only occur for ARM encoding
5536            ALUWritePC(result); // setflags is always FALSE here
5537        else
5538            R[d] = result;
5539            if setflags then
5540                APSR.N = result<31>;
5541                APSR.Z = IsZeroBit(result);
5542                APSR.C = carry;
5543                // APSR.V unchanged
5544#endif
5545
5546    bool success = false;
5547
5548    if (ConditionPassed(opcode))
5549    {
5550        uint32_t Rd, Rn, Rm;
5551        ARM_ShifterType shift_t;
5552        uint32_t shift_n; // the shift applied to the value read from Rm
5553        bool setflags;
5554        uint32_t carry;
5555        switch (encoding)
5556        {
5557        case eEncodingT1:
5558            Rd = Rn = Bits32(opcode, 2, 0);
5559            Rm = Bits32(opcode, 5, 3);
5560            setflags = !InITBlock();
5561            shift_t = SRType_LSL;
5562            shift_n = 0;
5563            break;
5564        case eEncodingT2:
5565            Rd = Bits32(opcode, 11, 8);
5566            Rn = Bits32(opcode, 19, 16);
5567            Rm = Bits32(opcode, 3, 0);
5568            setflags = BitIsSet(opcode, 20);
5569            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5570            // if Rd == '1111' && S == '1' then SEE TST (register);
5571            if (Rd == 15 && setflags)
5572                return EmulateTSTReg(opcode, eEncodingT2);
5573            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5574                return false;
5575            break;
5576        case eEncodingA1:
5577            Rd = Bits32(opcode, 15, 12);
5578            Rn = Bits32(opcode, 19, 16);
5579            Rm = Bits32(opcode, 3, 0);
5580            setflags = BitIsSet(opcode, 20);
5581            shift_n = DecodeImmShiftARM(opcode, shift_t);
5582
5583            if (Rd == 15 && setflags)
5584                return EmulateSUBSPcLrEtc (opcode, encoding);
5585            break;
5586        default:
5587            return false;
5588        }
5589
5590        // Read the first operand.
5591        uint32_t val1 = ReadCoreReg(Rn, &success);
5592        if (!success)
5593            return false;
5594
5595        // Read the second operand.
5596        uint32_t val2 = ReadCoreReg(Rm, &success);
5597        if (!success)
5598            return false;
5599
5600        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5601        if (!success)
5602            return false;
5603        uint32_t result = val1 & shifted;
5604
5605        EmulateInstruction::Context context;
5606        context.type = EmulateInstruction::eContextImmediate;
5607        context.SetNoArgs ();
5608
5609        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5610            return false;
5611    }
5612    return true;
5613}
5614
5615// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5616// immediate value, and writes the result to the destination register.  It can optionally update the
5617// condition flags based on the result.
5618bool
5619EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5620{
5621#if 0
5622    // ARM pseudo code...
5623    if ConditionPassed() then
5624        EncodingSpecificOperations();
5625        result = R[n] AND NOT(imm32);
5626        if d == 15 then         // Can only occur for ARM encoding
5627            ALUWritePC(result); // setflags is always FALSE here
5628        else
5629            R[d] = result;
5630            if setflags then
5631                APSR.N = result<31>;
5632                APSR.Z = IsZeroBit(result);
5633                APSR.C = carry;
5634                // APSR.V unchanged
5635#endif
5636
5637    bool success = false;
5638
5639    if (ConditionPassed(opcode))
5640    {
5641        uint32_t Rd, Rn;
5642        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5643        bool setflags;
5644        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5645        switch (encoding)
5646        {
5647        case eEncodingT1:
5648            Rd = Bits32(opcode, 11, 8);
5649            Rn = Bits32(opcode, 19, 16);
5650            setflags = BitIsSet(opcode, 20);
5651            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5652            if (BadReg(Rd) || BadReg(Rn))
5653                return false;
5654            break;
5655        case eEncodingA1:
5656            Rd = Bits32(opcode, 15, 12);
5657            Rn = Bits32(opcode, 19, 16);
5658            setflags = BitIsSet(opcode, 20);
5659            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5660
5661            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5662            if (Rd == 15 && setflags)
5663                return EmulateSUBSPcLrEtc (opcode, encoding);
5664            break;
5665        default:
5666            return false;
5667        }
5668
5669        // Read the first operand.
5670        uint32_t val1 = ReadCoreReg(Rn, &success);
5671        if (!success)
5672            return false;
5673
5674        uint32_t result = val1 & ~imm32;
5675
5676        EmulateInstruction::Context context;
5677        context.type = EmulateInstruction::eContextImmediate;
5678        context.SetNoArgs ();
5679
5680        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5681            return false;
5682    }
5683    return true;
5684}
5685
5686// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5687// optionally-shifted register value, and writes the result to the destination register.
5688// It can optionally update the condition flags based on the result.
5689bool
5690EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5691{
5692#if 0
5693    // ARM pseudo code...
5694    if ConditionPassed() then
5695        EncodingSpecificOperations();
5696        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5697        result = R[n] AND NOT(shifted);
5698        if d == 15 then         // Can only occur for ARM encoding
5699            ALUWritePC(result); // setflags is always FALSE here
5700        else
5701            R[d] = result;
5702            if setflags then
5703                APSR.N = result<31>;
5704                APSR.Z = IsZeroBit(result);
5705                APSR.C = carry;
5706                // APSR.V unchanged
5707#endif
5708
5709    bool success = false;
5710
5711    if (ConditionPassed(opcode))
5712    {
5713        uint32_t Rd, Rn, Rm;
5714        ARM_ShifterType shift_t;
5715        uint32_t shift_n; // the shift applied to the value read from Rm
5716        bool setflags;
5717        uint32_t carry;
5718        switch (encoding)
5719        {
5720        case eEncodingT1:
5721            Rd = Rn = Bits32(opcode, 2, 0);
5722            Rm = Bits32(opcode, 5, 3);
5723            setflags = !InITBlock();
5724            shift_t = SRType_LSL;
5725            shift_n = 0;
5726            break;
5727        case eEncodingT2:
5728            Rd = Bits32(opcode, 11, 8);
5729            Rn = Bits32(opcode, 19, 16);
5730            Rm = Bits32(opcode, 3, 0);
5731            setflags = BitIsSet(opcode, 20);
5732            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5733            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5734                return false;
5735            break;
5736        case eEncodingA1:
5737            Rd = Bits32(opcode, 15, 12);
5738            Rn = Bits32(opcode, 19, 16);
5739            Rm = Bits32(opcode, 3, 0);
5740            setflags = BitIsSet(opcode, 20);
5741            shift_n = DecodeImmShiftARM(opcode, shift_t);
5742
5743            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5744            if (Rd == 15 && setflags)
5745                return EmulateSUBSPcLrEtc (opcode, encoding);
5746            break;
5747        default:
5748            return false;
5749        }
5750
5751        // Read the first operand.
5752        uint32_t val1 = ReadCoreReg(Rn, &success);
5753        if (!success)
5754            return false;
5755
5756        // Read the second operand.
5757        uint32_t val2 = ReadCoreReg(Rm, &success);
5758        if (!success)
5759            return false;
5760
5761        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5762        if (!success)
5763            return false;
5764        uint32_t result = val1 & ~shifted;
5765
5766        EmulateInstruction::Context context;
5767        context.type = EmulateInstruction::eContextImmediate;
5768        context.SetNoArgs ();
5769
5770        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5771            return false;
5772    }
5773    return true;
5774}
5775
5776// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5777// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5778bool
5779EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5780{
5781#if 0
5782    if ConditionPassed() then
5783        EncodingSpecificOperations();
5784        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5785        address = if index then offset_addr else R[n];
5786        data = MemU[address,4];
5787        if wback then R[n] = offset_addr;
5788        if t == 15 then
5789            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5790        elsif UnalignedSupport() || address<1:0> = '00' then
5791            R[t] = data;
5792        else // Can only apply before ARMv7
5793            R[t] = ROR(data, 8*UInt(address<1:0>));
5794#endif
5795
5796    bool success = false;
5797
5798    if (ConditionPassed(opcode))
5799    {
5800        const uint32_t addr_byte_size = GetAddressByteSize();
5801
5802        uint32_t t;
5803        uint32_t n;
5804        uint32_t imm32;
5805        bool index;
5806        bool add;
5807        bool wback;
5808
5809        switch (encoding)
5810        {
5811            case eEncodingA1:
5812                // if Rn == '1111' then SEE LDR (literal);
5813                // if P == '0' && W == '1' then SEE LDRT;
5814                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5815                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5816                t = Bits32 (opcode, 15, 12);
5817                n = Bits32 (opcode, 19, 16);
5818                imm32 = Bits32 (opcode, 11, 0);
5819
5820                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5821                index = BitIsSet (opcode, 24);
5822                add = BitIsSet (opcode, 23);
5823                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5824
5825                // if wback && n == t then UNPREDICTABLE;
5826                if (wback && (n == t))
5827                    return false;
5828
5829                break;
5830
5831            default:
5832                return false;
5833        }
5834
5835        addr_t address;
5836        addr_t offset_addr;
5837        addr_t base_address = ReadCoreReg (n, &success);
5838        if (!success)
5839            return false;
5840
5841        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5842        if (add)
5843            offset_addr = base_address + imm32;
5844        else
5845            offset_addr = base_address - imm32;
5846
5847        // address = if index then offset_addr else R[n];
5848        if (index)
5849            address = offset_addr;
5850        else
5851            address = base_address;
5852
5853        // data = MemU[address,4];
5854
5855        RegisterInfo base_reg;
5856        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5857
5858        EmulateInstruction::Context context;
5859        context.type = eContextRegisterLoad;
5860        context.SetRegisterPlusOffset (base_reg, address - base_address);
5861
5862        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5863        if (!success)
5864            return false;
5865
5866        // if wback then R[n] = offset_addr;
5867        if (wback)
5868        {
5869            context.type = eContextAdjustBaseRegister;
5870            context.SetAddress (offset_addr);
5871            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5872                return false;
5873        }
5874
5875        // if t == 15 then
5876        if (t == 15)
5877        {
5878            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5879            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5880            {
5881                // LoadWritePC (data);
5882                context.type = eContextRegisterLoad;
5883                context.SetRegisterPlusOffset (base_reg, address - base_address);
5884                LoadWritePC (context, data);
5885            }
5886            else
5887                  return false;
5888        }
5889        // elsif UnalignedSupport() || address<1:0> = '00' then
5890        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5891        {
5892            // R[t] = data;
5893            context.type = eContextRegisterLoad;
5894            context.SetRegisterPlusOffset (base_reg, address - base_address);
5895            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5896                return false;
5897        }
5898        // else // Can only apply before ARMv7
5899        else
5900        {
5901            // R[t] = ROR(data, 8*UInt(address<1:0>));
5902            data = ROR (data, Bits32 (address, 1, 0), &success);
5903            if (!success)
5904                return false;
5905            context.type = eContextRegisterLoad;
5906            context.SetImmediate (data);
5907            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5908                return false;
5909        }
5910
5911    }
5912    return true;
5913}
5914
5915// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5916// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5917bool
5918EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5919{
5920#if 0
5921    if ConditionPassed() then
5922        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5923        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5924        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5925        address = if index then offset_addr else R[n];
5926        data = MemU[address,4];
5927        if wback then R[n] = offset_addr;
5928        if t == 15 then
5929            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5930        elsif UnalignedSupport() || address<1:0> = '00' then
5931            R[t] = data;
5932        else // Can only apply before ARMv7
5933            if CurrentInstrSet() == InstrSet_ARM then
5934                R[t] = ROR(data, 8*UInt(address<1:0>));
5935            else
5936                R[t] = bits(32) UNKNOWN;
5937#endif
5938
5939    bool success = false;
5940
5941    if (ConditionPassed(opcode))
5942    {
5943        const uint32_t addr_byte_size = GetAddressByteSize();
5944
5945        uint32_t t;
5946        uint32_t n;
5947        uint32_t m;
5948        bool index;
5949        bool add;
5950        bool wback;
5951        ARM_ShifterType shift_t;
5952        uint32_t shift_n;
5953
5954        switch (encoding)
5955        {
5956            case eEncodingT1:
5957                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5958                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5959                t = Bits32 (opcode, 2, 0);
5960                n = Bits32 (opcode, 5, 3);
5961                m = Bits32 (opcode, 8, 6);
5962
5963                // index = TRUE; add = TRUE; wback = FALSE;
5964                index = true;
5965                add = true;
5966                wback = false;
5967
5968                // (shift_t, shift_n) = (SRType_LSL, 0);
5969                shift_t = SRType_LSL;
5970                shift_n = 0;
5971
5972                break;
5973
5974            case eEncodingT2:
5975                // if Rn == '1111' then SEE LDR (literal);
5976                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5977                t = Bits32 (opcode, 15, 12);
5978                n = Bits32 (opcode, 19, 16);
5979                m = Bits32 (opcode, 3, 0);
5980
5981                // index = TRUE; add = TRUE; wback = FALSE;
5982                index = true;
5983                add = true;
5984                wback = false;
5985
5986                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5987                shift_t = SRType_LSL;
5988                shift_n = Bits32 (opcode, 5, 4);
5989
5990                // if BadReg(m) then UNPREDICTABLE;
5991                if (BadReg (m))
5992                    return false;
5993
5994                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5995                if ((t == 15) && InITBlock() && !LastInITBlock())
5996                    return false;
5997
5998                break;
5999
6000            case eEncodingA1:
6001            {
6002                // if P == '0' && W == '1' then SEE LDRT;
6003                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6004                t = Bits32 (opcode, 15, 12);
6005                n = Bits32 (opcode, 19, 16);
6006                m = Bits32 (opcode, 3, 0);
6007
6008                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6009                index = BitIsSet (opcode, 24);
6010                add = BitIsSet (opcode, 23);
6011                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6012
6013                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6014                uint32_t type = Bits32 (opcode, 6, 5);
6015                uint32_t imm5 = Bits32 (opcode, 11, 7);
6016                shift_n = DecodeImmShift (type, imm5, shift_t);
6017
6018                // if m == 15 then UNPREDICTABLE;
6019                if (m == 15)
6020                    return false;
6021
6022                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6023                if (wback && ((n == 15) || (n == t)))
6024                    return false;
6025            }
6026                break;
6027
6028
6029            default:
6030                return false;
6031        }
6032
6033        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6034        if (!success)
6035            return false;
6036
6037        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6038        if (!success)
6039            return false;
6040
6041        addr_t offset_addr;
6042        addr_t address;
6043
6044        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6045        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6046        if (!success)
6047            return false;
6048
6049        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6050        if (add)
6051            offset_addr = Rn + offset;
6052        else
6053            offset_addr = Rn - offset;
6054
6055        // address = if index then offset_addr else R[n];
6056            if (index)
6057                address = offset_addr;
6058            else
6059                address = Rn;
6060
6061        // data = MemU[address,4];
6062        RegisterInfo base_reg;
6063        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6064
6065        EmulateInstruction::Context context;
6066        context.type = eContextRegisterLoad;
6067        context.SetRegisterPlusOffset (base_reg, address - Rn);
6068
6069        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6070        if (!success)
6071            return false;
6072
6073        // if wback then R[n] = offset_addr;
6074        if (wback)
6075        {
6076            context.type = eContextAdjustBaseRegister;
6077            context.SetAddress (offset_addr);
6078            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6079                return false;
6080        }
6081
6082        // if t == 15 then
6083        if (t == 15)
6084        {
6085            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6086            if (BitIsClear (address, 1) && BitIsClear (address, 0))
6087            {
6088                context.type = eContextRegisterLoad;
6089                context.SetRegisterPlusOffset (base_reg, address - Rn);
6090                LoadWritePC (context, data);
6091            }
6092            else
6093                return false;
6094        }
6095        // elsif UnalignedSupport() || address<1:0> = '00' then
6096        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6097        {
6098            // R[t] = data;
6099            context.type = eContextRegisterLoad;
6100            context.SetRegisterPlusOffset (base_reg, address - Rn);
6101            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6102                return false;
6103        }
6104        else // Can only apply before ARMv7
6105        {
6106            // if CurrentInstrSet() == InstrSet_ARM then
6107            if (CurrentInstrSet () == eModeARM)
6108            {
6109                // R[t] = ROR(data, 8*UInt(address<1:0>));
6110                data = ROR (data, Bits32 (address, 1, 0), &success);
6111                if (!success)
6112                    return false;
6113                context.type = eContextRegisterLoad;
6114                context.SetImmediate (data);
6115                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6116                    return false;
6117            }
6118            else
6119            {
6120                // R[t] = bits(32) UNKNOWN;
6121                WriteBits32Unknown (t);
6122            }
6123        }
6124    }
6125    return true;
6126}
6127
6128// LDRB (immediate, Thumb)
6129bool
6130EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6131{
6132#if 0
6133    if ConditionPassed() then
6134        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6135        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6136        address = if index then offset_addr else R[n];
6137        R[t] = ZeroExtend(MemU[address,1], 32);
6138        if wback then R[n] = offset_addr;
6139#endif
6140
6141    bool success = false;
6142
6143    if (ConditionPassed(opcode))
6144    {
6145        uint32_t t;
6146        uint32_t n;
6147        uint32_t imm32;
6148        bool index;
6149        bool add;
6150        bool wback;
6151
6152        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6153        switch (encoding)
6154        {
6155            case eEncodingT1:
6156                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6157                t = Bits32 (opcode, 2, 0);
6158                n = Bits32 (opcode, 5, 3);
6159                imm32 = Bits32 (opcode, 10, 6);
6160
6161                // index = TRUE; add = TRUE; wback = FALSE;
6162                index = true;
6163                add = true;
6164                wback= false;
6165
6166                break;
6167
6168            case eEncodingT2:
6169                // if Rt == '1111' then SEE PLD;
6170                // if Rn == '1111' then SEE LDRB (literal);
6171                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6172                t = Bits32 (opcode, 15, 12);
6173                n = Bits32 (opcode, 19, 16);
6174                imm32 = Bits32 (opcode, 11, 0);
6175
6176                // index = TRUE; add = TRUE; wback = FALSE;
6177                index = true;
6178                add = true;
6179                wback = false;
6180
6181                // if t == 13 then UNPREDICTABLE;
6182                if (t == 13)
6183                    return false;
6184
6185                break;
6186
6187            case eEncodingT3:
6188                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6189                // if Rn == '1111' then SEE LDRB (literal);
6190                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6191                // if P == '0' && W == '0' then UNDEFINED;
6192                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6193                    return false;
6194
6195                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6196                t = Bits32 (opcode, 15, 12);
6197                n = Bits32 (opcode, 19, 16);
6198                imm32 = Bits32 (opcode, 7, 0);
6199
6200                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6201                index = BitIsSet (opcode, 10);
6202                add = BitIsSet (opcode, 9);
6203                wback = BitIsSet (opcode, 8);
6204
6205                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6206                if (BadReg (t) || (wback && (n == t)))
6207                    return false;
6208
6209                break;
6210
6211            default:
6212                return false;
6213        }
6214
6215        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6216        if (!success)
6217            return false;
6218
6219        addr_t address;
6220        addr_t offset_addr;
6221
6222        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6223        if (add)
6224            offset_addr = Rn + imm32;
6225        else
6226            offset_addr = Rn - imm32;
6227
6228        // address = if index then offset_addr else R[n];
6229        if (index)
6230            address = offset_addr;
6231        else
6232            address = Rn;
6233
6234        // R[t] = ZeroExtend(MemU[address,1], 32);
6235        RegisterInfo base_reg;
6236        RegisterInfo data_reg;
6237        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6238        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6239
6240        EmulateInstruction::Context context;
6241        context.type = eContextRegisterLoad;
6242        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6243
6244        uint64_t data = MemURead (context, address, 1, 0, &success);
6245        if (!success)
6246            return false;
6247
6248        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6249            return false;
6250
6251        // if wback then R[n] = offset_addr;
6252        if (wback)
6253        {
6254            context.type = eContextAdjustBaseRegister;
6255            context.SetAddress (offset_addr);
6256            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6257                return false;
6258        }
6259    }
6260    return true;
6261}
6262
6263// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6264// zero-extends it to form a 32-bit word and writes it to a register.
6265bool
6266EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6267{
6268#if 0
6269    if ConditionPassed() then
6270        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6271        base = Align(PC,4);
6272        address = if add then (base + imm32) else (base - imm32);
6273        R[t] = ZeroExtend(MemU[address,1], 32);
6274#endif
6275
6276    bool success = false;
6277
6278    if (ConditionPassed(opcode))
6279    {
6280        uint32_t t;
6281        uint32_t imm32;
6282        bool add;
6283        switch (encoding)
6284        {
6285            case eEncodingT1:
6286                // if Rt == '1111' then SEE PLD;
6287                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6288                t = Bits32 (opcode, 15, 12);
6289                imm32 = Bits32 (opcode, 11, 0);
6290                add = BitIsSet (opcode, 23);
6291
6292                // if t == 13 then UNPREDICTABLE;
6293                if (t == 13)
6294                    return false;
6295
6296                break;
6297
6298            case eEncodingA1:
6299                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6300                t = Bits32 (opcode, 15, 12);
6301                imm32 = Bits32 (opcode, 11, 0);
6302                add = BitIsSet (opcode, 23);
6303
6304                // if t == 15 then UNPREDICTABLE;
6305                if (t == 15)
6306                    return false;
6307                break;
6308
6309            default:
6310                return false;
6311        }
6312
6313        // base = Align(PC,4);
6314        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6315        if (!success)
6316            return false;
6317
6318        uint32_t base = AlignPC (pc_val);
6319
6320        addr_t address;
6321        // address = if add then (base + imm32) else (base - imm32);
6322        if (add)
6323            address = base + imm32;
6324        else
6325            address = base - imm32;
6326
6327        // R[t] = ZeroExtend(MemU[address,1], 32);
6328        EmulateInstruction::Context context;
6329        context.type = eContextRelativeBranchImmediate;
6330        context.SetImmediate (address - base);
6331
6332        uint64_t data = MemURead (context, address, 1, 0, &success);
6333        if (!success)
6334            return false;
6335
6336        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6337            return false;
6338    }
6339    return true;
6340}
6341
6342// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6343// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6344// optionally be shifted.
6345bool
6346EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6347{
6348#if 0
6349    if ConditionPassed() then
6350        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6351        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6352        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6353        address = if index then offset_addr else R[n];
6354        R[t] = ZeroExtend(MemU[address,1],32);
6355        if wback then R[n] = offset_addr;
6356#endif
6357
6358    bool success = false;
6359
6360    if (ConditionPassed(opcode))
6361    {
6362        uint32_t t;
6363        uint32_t n;
6364        uint32_t m;
6365        bool index;
6366        bool add;
6367        bool wback;
6368        ARM_ShifterType shift_t;
6369        uint32_t shift_n;
6370
6371        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6372        switch (encoding)
6373        {
6374            case eEncodingT1:
6375                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6376                t = Bits32 (opcode, 2, 0);
6377                n = Bits32 (opcode, 5, 3);
6378                m = Bits32 (opcode, 8, 6);
6379
6380                // index = TRUE; add = TRUE; wback = FALSE;
6381                index = true;
6382                add = true;
6383                wback = false;
6384
6385                // (shift_t, shift_n) = (SRType_LSL, 0);
6386                shift_t = SRType_LSL;
6387                shift_n = 0;
6388                break;
6389
6390            case eEncodingT2:
6391                // if Rt == '1111' then SEE PLD;
6392                // if Rn == '1111' then SEE LDRB (literal);
6393                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6394                t = Bits32 (opcode, 15, 12);
6395                n = Bits32 (opcode, 19, 16);
6396                m = Bits32 (opcode, 3, 0);
6397
6398                // index = TRUE; add = TRUE; wback = FALSE;
6399                index = true;
6400                add = true;
6401                wback = false;
6402
6403                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6404                shift_t = SRType_LSL;
6405                shift_n = Bits32 (opcode, 5, 4);
6406
6407                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6408                if ((t == 13) || BadReg (m))
6409                    return false;
6410                break;
6411
6412            case eEncodingA1:
6413            {
6414                // if P == '0' && W == '1' then SEE LDRBT;
6415                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6416                t = Bits32 (opcode, 15, 12);
6417                n = Bits32 (opcode, 19, 16);
6418                m = Bits32 (opcode, 3, 0);
6419
6420                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6421                index = BitIsSet (opcode, 24);
6422                add = BitIsSet (opcode, 23);
6423                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6424
6425                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6426                uint32_t type = Bits32 (opcode, 6, 5);
6427                uint32_t imm5 = Bits32 (opcode, 11, 7);
6428                shift_n = DecodeImmShift (type, imm5, shift_t);
6429
6430                // if t == 15 || m == 15 then UNPREDICTABLE;
6431                if ((t == 15) || (m == 15))
6432                    return false;
6433
6434                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6435                if (wback && ((n == 15) || (n == t)))
6436                    return false;
6437            }
6438                break;
6439
6440            default:
6441                return false;
6442        }
6443
6444        addr_t offset_addr;
6445        addr_t address;
6446
6447        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6448        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6449        if (!success)
6450            return false;
6451
6452        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6453        if (!success)
6454            return false;
6455
6456        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6457        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6458        if (!success)
6459            return false;
6460
6461        if (add)
6462            offset_addr = Rn + offset;
6463        else
6464            offset_addr = Rn - offset;
6465
6466        // address = if index then offset_addr else R[n];
6467        if (index)
6468            address = offset_addr;
6469        else
6470            address = Rn;
6471
6472        // R[t] = ZeroExtend(MemU[address,1],32);
6473        RegisterInfo base_reg;
6474        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6475
6476        EmulateInstruction::Context context;
6477        context.type = eContextRegisterLoad;
6478        context.SetRegisterPlusOffset (base_reg, address - Rn);
6479
6480        uint64_t data = MemURead (context, address, 1, 0, &success);
6481        if (!success)
6482            return false;
6483
6484        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6485            return false;
6486
6487        // if wback then R[n] = offset_addr;
6488        if (wback)
6489        {
6490            context.type = eContextAdjustBaseRegister;
6491            context.SetAddress (offset_addr);
6492            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6493                return false;
6494        }
6495    }
6496    return true;
6497}
6498
6499// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6500// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6501// post-indexed, or pre-indexed addressing.
6502bool
6503EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6504{
6505#if 0
6506    if ConditionPassed() then
6507        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6508        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6509        address = if index then offset_addr else R[n];
6510        data = MemU[address,2];
6511        if wback then R[n] = offset_addr;
6512        if UnalignedSupport() || address<0> = '0' then
6513            R[t] = ZeroExtend(data, 32);
6514        else // Can only apply before ARMv7
6515            R[t] = bits(32) UNKNOWN;
6516#endif
6517
6518
6519    bool success = false;
6520
6521    if (ConditionPassed(opcode))
6522    {
6523        uint32_t t;
6524        uint32_t n;
6525        uint32_t imm32;
6526        bool index;
6527        bool add;
6528        bool wback;
6529
6530        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6531        switch (encoding)
6532        {
6533            case eEncodingT1:
6534                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6535                t = Bits32 (opcode, 2, 0);
6536                n = Bits32 (opcode, 5, 3);
6537                imm32 = Bits32 (opcode, 10, 6) << 1;
6538
6539                // index = TRUE; add = TRUE; wback = FALSE;
6540                index = true;
6541                add = true;
6542                wback = false;
6543
6544                break;
6545
6546            case eEncodingT2:
6547                // if Rt == '1111' then SEE "Unallocated memory hints";
6548                // if Rn == '1111' then SEE LDRH (literal);
6549                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6550                t = Bits32 (opcode, 15, 12);
6551                n = Bits32 (opcode, 19, 16);
6552                imm32 = Bits32 (opcode, 11, 0);
6553
6554                // index = TRUE; add = TRUE; wback = FALSE;
6555                index = true;
6556                add = true;
6557                wback = false;
6558
6559                // if t == 13 then UNPREDICTABLE;
6560                if (t == 13)
6561                    return false;
6562                break;
6563
6564            case eEncodingT3:
6565                // if Rn == '1111' then SEE LDRH (literal);
6566                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6567                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6568                // if P == '0' && W == '0' then UNDEFINED;
6569                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6570                    return false;
6571
6572                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6573                t = Bits32 (opcode, 15, 12);
6574                n = Bits32 (opcode, 19, 16);
6575                imm32 = Bits32 (opcode, 7, 0);
6576
6577                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6578                index = BitIsSet (opcode, 10);
6579                add = BitIsSet (opcode, 9);
6580                wback = BitIsSet (opcode, 8);
6581
6582                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6583                if (BadReg (t) || (wback && (n == t)))
6584                    return false;
6585                break;
6586
6587            default:
6588                return false;
6589        }
6590
6591        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6592        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6593        if (!success)
6594            return false;
6595
6596        addr_t offset_addr;
6597        addr_t address;
6598
6599        if (add)
6600            offset_addr = Rn + imm32;
6601        else
6602            offset_addr = Rn - imm32;
6603
6604        // address = if index then offset_addr else R[n];
6605        if (index)
6606            address = offset_addr;
6607        else
6608            address = Rn;
6609
6610        // data = MemU[address,2];
6611        RegisterInfo base_reg;
6612        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6613
6614        EmulateInstruction::Context context;
6615        context.type = eContextRegisterLoad;
6616        context.SetRegisterPlusOffset (base_reg, address - Rn);
6617
6618        uint64_t data = MemURead (context, address, 2, 0, &success);
6619        if (!success)
6620            return false;
6621
6622        // if wback then R[n] = offset_addr;
6623        if (wback)
6624        {
6625            context.type = eContextAdjustBaseRegister;
6626            context.SetAddress (offset_addr);
6627            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6628                return false;
6629        }
6630
6631        // if UnalignedSupport() || address<0> = '0' then
6632        if (UnalignedSupport () || BitIsClear (address, 0))
6633        {
6634            // R[t] = ZeroExtend(data, 32);
6635            context.type = eContextRegisterLoad;
6636            context.SetRegisterPlusOffset (base_reg, address - Rn);
6637            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6638                return false;
6639        }
6640        else // Can only apply before ARMv7
6641        {
6642            // R[t] = bits(32) UNKNOWN;
6643            WriteBits32Unknown (t);
6644        }
6645    }
6646    return true;
6647}
6648
6649// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6650// zero-extends it to form a 32-bit word, and writes it to a register.
6651bool
6652EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6653{
6654#if 0
6655    if ConditionPassed() then
6656        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6657        base = Align(PC,4);
6658        address = if add then (base + imm32) else (base - imm32);
6659        data = MemU[address,2];
6660        if UnalignedSupport() || address<0> = '0' then
6661            R[t] = ZeroExtend(data, 32);
6662        else // Can only apply before ARMv7
6663            R[t] = bits(32) UNKNOWN;
6664#endif
6665
6666    bool success = false;
6667
6668    if (ConditionPassed(opcode))
6669    {
6670        uint32_t t;
6671        uint32_t imm32;
6672        bool add;
6673
6674        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6675        switch (encoding)
6676        {
6677            case eEncodingT1:
6678                // if Rt == '1111' then SEE "Unallocated memory hints";
6679                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6680                t = Bits32 (opcode, 15, 12);
6681                imm32 = Bits32 (opcode, 11, 0);
6682                add = BitIsSet (opcode, 23);
6683
6684                // if t == 13 then UNPREDICTABLE;
6685                if (t == 13)
6686                    return false;
6687
6688                break;
6689
6690            case eEncodingA1:
6691            {
6692                uint32_t imm4H = Bits32 (opcode, 11, 8);
6693                uint32_t imm4L = Bits32 (opcode, 3, 0);
6694
6695                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6696                t = Bits32 (opcode, 15, 12);
6697                imm32 = (imm4H << 4) | imm4L;
6698                add = BitIsSet (opcode, 23);
6699
6700                // if t == 15 then UNPREDICTABLE;
6701                if (t == 15)
6702                    return false;
6703                break;
6704            }
6705
6706            default:
6707                return false;
6708        }
6709
6710        // base = Align(PC,4);
6711        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6712        if (!success)
6713            return false;
6714
6715        addr_t base = AlignPC (pc_value);
6716        addr_t address;
6717
6718        // address = if add then (base + imm32) else (base - imm32);
6719        if (add)
6720            address = base + imm32;
6721        else
6722            address = base - imm32;
6723
6724        // data = MemU[address,2];
6725        RegisterInfo base_reg;
6726        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6727
6728        EmulateInstruction::Context context;
6729        context.type = eContextRegisterLoad;
6730        context.SetRegisterPlusOffset (base_reg, address - base);
6731
6732        uint64_t data = MemURead (context, address, 2, 0, &success);
6733        if (!success)
6734            return false;
6735
6736
6737        // if UnalignedSupport() || address<0> = '0' then
6738        if (UnalignedSupport () || BitIsClear (address, 0))
6739        {
6740            // R[t] = ZeroExtend(data, 32);
6741            context.type = eContextRegisterLoad;
6742            context.SetRegisterPlusOffset (base_reg, address - base);
6743            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6744                return false;
6745
6746        }
6747        else // Can only apply before ARMv7
6748        {
6749            // R[t] = bits(32) UNKNOWN;
6750            WriteBits32Unknown (t);
6751        }
6752    }
6753    return true;
6754}
6755
6756// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6757// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6758// be shifted left by 0, 1, 2, or 3 bits.
6759bool
6760EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6761{
6762#if 0
6763    if ConditionPassed() then
6764        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6765        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6766        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6767        address = if index then offset_addr else R[n];
6768        data = MemU[address,2];
6769        if wback then R[n] = offset_addr;
6770        if UnalignedSupport() || address<0> = '0' then
6771            R[t] = ZeroExtend(data, 32);
6772        else // Can only apply before ARMv7
6773            R[t] = bits(32) UNKNOWN;
6774#endif
6775
6776    bool success = false;
6777
6778    if (ConditionPassed(opcode))
6779    {
6780        uint32_t t;
6781        uint32_t n;
6782        uint32_t m;
6783        bool index;
6784        bool add;
6785        bool wback;
6786        ARM_ShifterType shift_t;
6787        uint32_t shift_n;
6788
6789        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6790        switch (encoding)
6791        {
6792            case eEncodingT1:
6793                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6794                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6795                t = Bits32 (opcode, 2, 0);
6796                n = Bits32 (opcode, 5, 3);
6797                m = Bits32 (opcode, 8, 6);
6798
6799                // index = TRUE; add = TRUE; wback = FALSE;
6800                index = true;
6801                add = true;
6802                wback = false;
6803
6804                // (shift_t, shift_n) = (SRType_LSL, 0);
6805                shift_t = SRType_LSL;
6806                shift_n = 0;
6807
6808                break;
6809
6810            case eEncodingT2:
6811                // if Rn == '1111' then SEE LDRH (literal);
6812                // if Rt == '1111' then SEE "Unallocated memory hints";
6813                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6814                t = Bits32 (opcode, 15, 12);
6815                n = Bits32 (opcode, 19, 16);
6816                m = Bits32 (opcode, 3, 0);
6817
6818                // index = TRUE; add = TRUE; wback = FALSE;
6819                index = true;
6820                add = true;
6821                wback = false;
6822
6823                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6824                shift_t = SRType_LSL;
6825                shift_n = Bits32 (opcode, 5, 4);
6826
6827                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6828                if ((t == 13) || BadReg (m))
6829                    return false;
6830                break;
6831
6832            case eEncodingA1:
6833                // if P == '0' && W == '1' then SEE LDRHT;
6834                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6835                t = Bits32 (opcode, 15, 12);
6836                n = Bits32 (opcode, 19, 16);
6837                m = Bits32 (opcode, 3, 0);
6838
6839                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6840                index = BitIsSet (opcode, 24);
6841                add = BitIsSet (opcode, 23);
6842                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6843
6844                // (shift_t, shift_n) = (SRType_LSL, 0);
6845                shift_t = SRType_LSL;
6846                shift_n = 0;
6847
6848                // if t == 15 || m == 15 then UNPREDICTABLE;
6849                if ((t == 15) || (m == 15))
6850                    return false;
6851
6852                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6853                if (wback && ((n == 15) || (n == t)))
6854                    return false;
6855
6856                break;
6857
6858            default:
6859                return false;
6860        }
6861
6862        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6863
6864        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6865        if (!success)
6866            return false;
6867
6868        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6869        if (!success)
6870            return false;
6871
6872        addr_t offset_addr;
6873        addr_t address;
6874
6875        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6876        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6877        if (!success)
6878            return false;
6879
6880        if (add)
6881            offset_addr = Rn + offset;
6882        else
6883            offset_addr = Rn - offset;
6884
6885        // address = if index then offset_addr else R[n];
6886        if (index)
6887            address = offset_addr;
6888        else
6889            address = Rn;
6890
6891        // data = MemU[address,2];
6892        RegisterInfo base_reg;
6893        RegisterInfo offset_reg;
6894        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6895        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6896
6897        EmulateInstruction::Context context;
6898        context.type = eContextRegisterLoad;
6899        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6900        uint64_t data = MemURead (context, address, 2, 0, &success);
6901        if (!success)
6902            return false;
6903
6904        // if wback then R[n] = offset_addr;
6905        if (wback)
6906        {
6907            context.type = eContextAdjustBaseRegister;
6908            context.SetAddress (offset_addr);
6909            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6910                return false;
6911        }
6912
6913        // if UnalignedSupport() || address<0> = '0' then
6914        if (UnalignedSupport() || BitIsClear (address, 0))
6915        {
6916            // R[t] = ZeroExtend(data, 32);
6917            context.type = eContextRegisterLoad;
6918            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6919            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6920                return false;
6921        }
6922        else // Can only apply before ARMv7
6923        {
6924            // R[t] = bits(32) UNKNOWN;
6925            WriteBits32Unknown (t);
6926        }
6927    }
6928    return true;
6929}
6930
6931// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6932// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6933// or pre-indexed addressing.
6934bool
6935EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6936{
6937#if 0
6938    if ConditionPassed() then
6939        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6940        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6941        address = if index then offset_addr else R[n];
6942        R[t] = SignExtend(MemU[address,1], 32);
6943        if wback then R[n] = offset_addr;
6944#endif
6945
6946    bool success = false;
6947
6948    if (ConditionPassed(opcode))
6949    {
6950        uint32_t t;
6951        uint32_t n;
6952        uint32_t imm32;
6953        bool index;
6954        bool add;
6955        bool wback;
6956
6957        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6958        switch (encoding)
6959        {
6960            case eEncodingT1:
6961                // if Rt == '1111' then SEE PLI;
6962                // if Rn == '1111' then SEE LDRSB (literal);
6963                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6964                t = Bits32 (opcode, 15, 12);
6965                n = Bits32 (opcode, 19, 16);
6966                imm32 = Bits32 (opcode, 11, 0);
6967
6968                // index = TRUE; add = TRUE; wback = FALSE;
6969                index = true;
6970                add = true;
6971                wback = false;
6972
6973                // if t == 13 then UNPREDICTABLE;
6974                if (t == 13)
6975                    return false;
6976
6977                break;
6978
6979            case eEncodingT2:
6980                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6981                // if Rn == '1111' then SEE LDRSB (literal);
6982                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6983                // if P == '0' && W == '0' then UNDEFINED;
6984                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6985                    return false;
6986
6987                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6988                t = Bits32 (opcode, 15, 12);
6989                n = Bits32 (opcode, 19, 16);
6990                imm32 = Bits32 (opcode, 7, 0);
6991
6992                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6993                index = BitIsSet (opcode, 10);
6994                add = BitIsSet (opcode, 9);
6995                wback = BitIsSet (opcode, 8);
6996
6997                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6998                  if (((t == 13) || ((t == 15)
6999                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7000                      || (wback && (n == t)))
7001                    return false;
7002
7003                break;
7004
7005            case eEncodingA1:
7006            {
7007                // if Rn == '1111' then SEE LDRSB (literal);
7008                // if P == '0' && W == '1' then SEE LDRSBT;
7009                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7010                t = Bits32 (opcode, 15, 12);
7011                n = Bits32 (opcode, 19, 16);
7012
7013                uint32_t imm4H = Bits32 (opcode, 11, 8);
7014                uint32_t imm4L = Bits32 (opcode, 3, 0);
7015                imm32 = (imm4H << 4) | imm4L;
7016
7017                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7018                index = BitIsSet (opcode, 24);
7019                add = BitIsSet (opcode, 23);
7020                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7021
7022                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7023                if ((t == 15) || (wback && (n == t)))
7024                    return false;
7025
7026                break;
7027            }
7028
7029            default:
7030                return false;
7031        }
7032
7033        uint64_t Rn = ReadCoreReg (n, &success);
7034        if (!success)
7035            return false;
7036
7037        addr_t offset_addr;
7038        addr_t address;
7039
7040        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7041        if (add)
7042            offset_addr = Rn + imm32;
7043        else
7044            offset_addr = Rn - imm32;
7045
7046        // address = if index then offset_addr else R[n];
7047        if (index)
7048            address = offset_addr;
7049        else
7050            address = Rn;
7051
7052        // R[t] = SignExtend(MemU[address,1], 32);
7053        RegisterInfo base_reg;
7054        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7055
7056        EmulateInstruction::Context context;
7057        context.type = eContextRegisterLoad;
7058        context.SetRegisterPlusOffset (base_reg, address - Rn);
7059
7060        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7061        if (!success)
7062            return false;
7063
7064        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7065        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7066            return false;
7067
7068        // if wback then R[n] = offset_addr;
7069        if (wback)
7070        {
7071            context.type = eContextAdjustBaseRegister;
7072            context.SetAddress (offset_addr);
7073            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7074                return false;
7075        }
7076    }
7077
7078    return true;
7079}
7080
7081// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7082// sign-extends it to form a 32-bit word, and writes tit to a register.
7083bool
7084EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7085{
7086#if 0
7087    if ConditionPassed() then
7088        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7089        base = Align(PC,4);
7090        address = if add then (base + imm32) else (base - imm32);
7091        R[t] = SignExtend(MemU[address,1], 32);
7092#endif
7093
7094    bool success = false;
7095
7096    if (ConditionPassed(opcode))
7097    {
7098        uint32_t t;
7099        uint32_t imm32;
7100        bool add;
7101
7102        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7103        switch (encoding)
7104        {
7105            case eEncodingT1:
7106                // if Rt == '1111' then SEE PLI;
7107                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7108                t = Bits32 (opcode, 15, 12);
7109                imm32 = Bits32 (opcode, 11, 0);
7110                add = BitIsSet (opcode, 23);
7111
7112                // if t == 13 then UNPREDICTABLE;
7113                if (t == 13)
7114                    return false;
7115
7116                break;
7117
7118            case eEncodingA1:
7119            {
7120                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7121                t = Bits32 (opcode, 15, 12);
7122                uint32_t imm4H = Bits32 (opcode, 11, 8);
7123                uint32_t imm4L = Bits32 (opcode, 3, 0);
7124                imm32 = (imm4H << 4) | imm4L;
7125                add = BitIsSet (opcode, 23);
7126
7127                // if t == 15 then UNPREDICTABLE;
7128                if (t == 15)
7129                    return false;
7130
7131                break;
7132            }
7133
7134            default:
7135                return false;
7136        }
7137
7138        // base = Align(PC,4);
7139        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7140        if (!success)
7141            return false;
7142        uint64_t base = AlignPC (pc_value);
7143
7144        // address = if add then (base + imm32) else (base - imm32);
7145        addr_t address;
7146        if (add)
7147            address = base + imm32;
7148        else
7149            address = base - imm32;
7150
7151        // R[t] = SignExtend(MemU[address,1], 32);
7152        RegisterInfo base_reg;
7153        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7154
7155        EmulateInstruction::Context context;
7156        context.type = eContextRegisterLoad;
7157        context.SetRegisterPlusOffset (base_reg, address - base);
7158
7159        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7160        if (!success)
7161            return false;
7162
7163        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7164        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7165            return false;
7166    }
7167    return true;
7168}
7169
7170// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7171// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7172// shifted left by 0, 1, 2, or 3 bits.
7173bool
7174EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7175{
7176#if 0
7177    if ConditionPassed() then
7178        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7179        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7180        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7181        address = if index then offset_addr else R[n];
7182        R[t] = SignExtend(MemU[address,1], 32);
7183        if wback then R[n] = offset_addr;
7184#endif
7185
7186    bool success = false;
7187
7188    if (ConditionPassed(opcode))
7189    {
7190        uint32_t t;
7191        uint32_t n;
7192        uint32_t m;
7193        bool index;
7194        bool add;
7195        bool wback;
7196        ARM_ShifterType shift_t;
7197        uint32_t shift_n;
7198
7199        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7200        switch (encoding)
7201        {
7202            case eEncodingT1:
7203                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7204                t = Bits32 (opcode, 2, 0);
7205                n = Bits32 (opcode, 5, 3);
7206                m = Bits32 (opcode, 8, 6);
7207
7208                // index = TRUE; add = TRUE; wback = FALSE;
7209                index = true;
7210                add = true;
7211                wback = false;
7212
7213                // (shift_t, shift_n) = (SRType_LSL, 0);
7214                shift_t = SRType_LSL;
7215                shift_n = 0;
7216
7217                break;
7218
7219            case eEncodingT2:
7220                // if Rt == '1111' then SEE PLI;
7221                // if Rn == '1111' then SEE LDRSB (literal);
7222                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7223                t = Bits32 (opcode, 15, 12);
7224                n = Bits32 (opcode, 19, 16);
7225                m = Bits32 (opcode, 3, 0);
7226
7227                // index = TRUE; add = TRUE; wback = FALSE;
7228                index = true;
7229                add = true;
7230                wback = false;
7231
7232                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7233                shift_t = SRType_LSL;
7234                shift_n = Bits32 (opcode, 5, 4);
7235
7236                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7237                if ((t == 13) || BadReg (m))
7238                    return false;
7239                break;
7240
7241            case eEncodingA1:
7242                // if P == '0' && W == '1' then SEE LDRSBT;
7243                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7244                t = Bits32 (opcode, 15, 12);
7245                n = Bits32 (opcode, 19, 16);
7246                m = Bits32 (opcode, 3, 0);
7247
7248                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7249                index = BitIsSet (opcode, 24);
7250                add = BitIsSet (opcode, 23);
7251                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7252
7253                // (shift_t, shift_n) = (SRType_LSL, 0);
7254                shift_t = SRType_LSL;
7255                shift_n = 0;
7256
7257                // if t == 15 || m == 15 then UNPREDICTABLE;
7258                if ((t == 15) || (m == 15))
7259                    return false;
7260
7261                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7262                if (wback && ((n == 15) || (n == t)))
7263                    return false;
7264                break;
7265
7266            default:
7267                return false;
7268        }
7269
7270        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7271        if (!success)
7272            return false;
7273
7274        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7275        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7276        if (!success)
7277            return false;
7278
7279        addr_t offset_addr;
7280        addr_t address;
7281
7282        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7283        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7284        if (!success)
7285            return false;
7286
7287        if (add)
7288            offset_addr = Rn + offset;
7289        else
7290            offset_addr = Rn - offset;
7291
7292        // address = if index then offset_addr else R[n];
7293        if (index)
7294            address = offset_addr;
7295        else
7296            address = Rn;
7297
7298        // R[t] = SignExtend(MemU[address,1], 32);
7299        RegisterInfo base_reg;
7300        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7301        RegisterInfo offset_reg;
7302        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7303
7304        EmulateInstruction::Context context;
7305        context.type = eContextRegisterLoad;
7306        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7307
7308        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7309        if (!success)
7310            return false;
7311
7312        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7313        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7314            return false;
7315
7316        // if wback then R[n] = offset_addr;
7317        if (wback)
7318        {
7319            context.type = eContextAdjustBaseRegister;
7320            context.SetAddress (offset_addr);
7321            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7322                return false;
7323        }
7324    }
7325    return true;
7326}
7327
7328// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7329// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7330// pre-indexed addressing.
7331bool
7332EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7333{
7334#if 0
7335    if ConditionPassed() then
7336        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7337        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7338        address = if index then offset_addr else R[n];
7339        data = MemU[address,2];
7340        if wback then R[n] = offset_addr;
7341        if UnalignedSupport() || address<0> = '0' then
7342            R[t] = SignExtend(data, 32);
7343        else // Can only apply before ARMv7
7344            R[t] = bits(32) UNKNOWN;
7345#endif
7346
7347    bool success = false;
7348
7349    if (ConditionPassed(opcode))
7350    {
7351        uint32_t t;
7352        uint32_t n;
7353        uint32_t imm32;
7354        bool index;
7355        bool add;
7356        bool wback;
7357
7358        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7359        switch (encoding)
7360        {
7361            case eEncodingT1:
7362                // if Rn == '1111' then SEE LDRSH (literal);
7363                // if Rt == '1111' then SEE "Unallocated memory hints";
7364                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7365                t = Bits32 (opcode, 15, 12);
7366                n = Bits32 (opcode, 19, 16);
7367                imm32 = Bits32 (opcode, 11, 0);
7368
7369                // index = TRUE; add = TRUE; wback = FALSE;
7370                index = true;
7371                add = true;
7372                wback = false;
7373
7374                // if t == 13 then UNPREDICTABLE;
7375                if (t == 13)
7376                    return false;
7377
7378                break;
7379
7380            case eEncodingT2:
7381                // if Rn == '1111' then SEE LDRSH (literal);
7382                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7383                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7384                // if P == '0' && W == '0' then UNDEFINED;
7385                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7386                  return false;
7387
7388                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7389                t = Bits32 (opcode, 15, 12);
7390                n = Bits32 (opcode, 19, 16);
7391                imm32 = Bits32 (opcode, 7, 0);
7392
7393                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7394                index = BitIsSet (opcode, 10);
7395                add = BitIsSet (opcode, 9);
7396                wback = BitIsSet (opcode, 8);
7397
7398                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7399                if (BadReg (t) || (wback && (n == t)))
7400                    return false;
7401
7402                break;
7403
7404            case eEncodingA1:
7405            {
7406                // if Rn == '1111' then SEE LDRSH (literal);
7407                // if P == '0' && W == '1' then SEE LDRSHT;
7408                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7409                t = Bits32 (opcode, 15, 12);
7410                n = Bits32 (opcode, 19, 16);
7411                uint32_t imm4H = Bits32 (opcode, 11,8);
7412                uint32_t imm4L = Bits32 (opcode, 3, 0);
7413                imm32 = (imm4H << 4) | imm4L;
7414
7415                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7416                index = BitIsSet (opcode, 24);
7417                add = BitIsSet (opcode, 23);
7418                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7419
7420                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7421                if ((t == 15) || (wback && (n == t)))
7422                    return false;
7423
7424                break;
7425            }
7426
7427            default:
7428                return false;
7429        }
7430
7431        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7432        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7433        if (!success)
7434            return false;
7435
7436        addr_t offset_addr;
7437        if (add)
7438            offset_addr = Rn + imm32;
7439        else
7440            offset_addr = Rn - imm32;
7441
7442        // address = if index then offset_addr else R[n];
7443        addr_t address;
7444        if (index)
7445            address = offset_addr;
7446        else
7447            address = Rn;
7448
7449        // data = MemU[address,2];
7450        RegisterInfo base_reg;
7451        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7452
7453        EmulateInstruction::Context context;
7454        context.type = eContextRegisterLoad;
7455        context.SetRegisterPlusOffset (base_reg, address - Rn);
7456
7457        uint64_t data = MemURead (context, address, 2, 0, &success);
7458        if (!success)
7459            return false;
7460
7461        // if wback then R[n] = offset_addr;
7462        if (wback)
7463        {
7464            context.type = eContextAdjustBaseRegister;
7465            context.SetAddress (offset_addr);
7466            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7467                return false;
7468        }
7469
7470        // if UnalignedSupport() || address<0> = '0' then
7471        if (UnalignedSupport() || BitIsClear (address, 0))
7472        {
7473            // R[t] = SignExtend(data, 32);
7474            int64_t signed_data = llvm::SignExtend64<16>(data);
7475            context.type = eContextRegisterLoad;
7476            context.SetRegisterPlusOffset (base_reg, address - Rn);
7477            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7478                return false;
7479        }
7480        else // Can only apply before ARMv7
7481        {
7482            // R[t] = bits(32) UNKNOWN;
7483            WriteBits32Unknown (t);
7484        }
7485    }
7486    return true;
7487}
7488
7489// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7490// sign-extends it to from a 32-bit word, and writes it to a register.
7491bool
7492EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7493{
7494#if 0
7495    if ConditionPassed() then
7496        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7497        base = Align(PC,4);
7498        address = if add then (base + imm32) else (base - imm32);
7499        data = MemU[address,2];
7500        if UnalignedSupport() || address<0> = '0' then
7501            R[t] = SignExtend(data, 32);
7502        else // Can only apply before ARMv7
7503            R[t] = bits(32) UNKNOWN;
7504#endif
7505
7506    bool success = false;
7507
7508    if (ConditionPassed(opcode))
7509    {
7510        uint32_t t;
7511        uint32_t imm32;
7512        bool add;
7513
7514        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7515        switch (encoding)
7516        {
7517            case eEncodingT1:
7518                // if Rt == '1111' then SEE "Unallocated memory hints";
7519                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7520                t = Bits32  (opcode, 15, 12);
7521                imm32 = Bits32 (opcode, 11, 0);
7522                add = BitIsSet (opcode, 23);
7523
7524                // if t == 13 then UNPREDICTABLE;
7525                if (t == 13)
7526                    return false;
7527
7528                break;
7529
7530            case eEncodingA1:
7531            {
7532                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7533                t = Bits32 (opcode, 15, 12);
7534                uint32_t imm4H = Bits32 (opcode, 11, 8);
7535                uint32_t imm4L = Bits32 (opcode, 3, 0);
7536                imm32 = (imm4H << 4) | imm4L;
7537                add = BitIsSet (opcode, 23);
7538
7539                // if t == 15 then UNPREDICTABLE;
7540                if (t == 15)
7541                    return false;
7542
7543                break;
7544            }
7545            default:
7546                return false;
7547        }
7548
7549        // base = Align(PC,4);
7550        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7551        if (!success)
7552            return false;
7553
7554        uint64_t base = AlignPC (pc_value);
7555
7556        addr_t address;
7557        // address = if add then (base + imm32) else (base - imm32);
7558        if (add)
7559            address = base + imm32;
7560        else
7561            address = base - imm32;
7562
7563        // data = MemU[address,2];
7564        RegisterInfo base_reg;
7565        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7566
7567        EmulateInstruction::Context context;
7568        context.type = eContextRegisterLoad;
7569        context.SetRegisterPlusOffset (base_reg, imm32);
7570
7571        uint64_t data = MemURead (context, address, 2, 0, &success);
7572        if (!success)
7573            return false;
7574
7575        // if UnalignedSupport() || address<0> = '0' then
7576        if (UnalignedSupport() || BitIsClear (address, 0))
7577        {
7578            // R[t] = SignExtend(data, 32);
7579            int64_t signed_data = llvm::SignExtend64<16>(data);
7580            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7581                return false;
7582        }
7583        else // Can only apply before ARMv7
7584        {
7585            // R[t] = bits(32) UNKNOWN;
7586            WriteBits32Unknown (t);
7587        }
7588    }
7589    return true;
7590}
7591
7592// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7593// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7594// shifted left by 0, 1, 2, or 3 bits.
7595bool
7596EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7597{
7598#if 0
7599    if ConditionPassed() then
7600        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7601        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7602        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7603        address = if index then offset_addr else R[n];
7604        data = MemU[address,2];
7605        if wback then R[n] = offset_addr;
7606        if UnalignedSupport() || address<0> = '0' then
7607            R[t] = SignExtend(data, 32);
7608        else // Can only apply before ARMv7
7609            R[t] = bits(32) UNKNOWN;
7610#endif
7611
7612    bool success = false;
7613
7614    if (ConditionPassed(opcode))
7615    {
7616        uint32_t t;
7617        uint32_t n;
7618        uint32_t m;
7619        bool index;
7620        bool add;
7621        bool wback;
7622        ARM_ShifterType shift_t;
7623        uint32_t shift_n;
7624
7625        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7626        switch (encoding)
7627        {
7628            case eEncodingT1:
7629                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7630                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7631                t = Bits32 (opcode, 2, 0);
7632                n = Bits32 (opcode, 5, 3);
7633                m = Bits32 (opcode, 8, 6);
7634
7635                // index = TRUE; add = TRUE; wback = FALSE;
7636                index = true;
7637                add = true;
7638                wback = false;
7639
7640                // (shift_t, shift_n) = (SRType_LSL, 0);
7641                shift_t = SRType_LSL;
7642                shift_n = 0;
7643
7644                break;
7645
7646            case eEncodingT2:
7647                // if Rn == '1111' then SEE LDRSH (literal);
7648                // if Rt == '1111' then SEE "Unallocated memory hints";
7649                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7650                t = Bits32 (opcode, 15, 12);
7651                n = Bits32 (opcode, 19, 16);
7652                m = Bits32 (opcode, 3, 0);
7653
7654                // index = TRUE; add = TRUE; wback = FALSE;
7655                index = true;
7656                add = true;
7657                wback = false;
7658
7659                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7660                shift_t = SRType_LSL;
7661                shift_n = Bits32 (opcode, 5, 4);
7662
7663                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7664                if ((t == 13) || BadReg (m))
7665                    return false;
7666
7667                break;
7668
7669            case eEncodingA1:
7670                // if P == '0' && W == '1' then SEE LDRSHT;
7671                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7672                t = Bits32 (opcode, 15, 12);
7673                n = Bits32 (opcode, 19, 16);
7674                m = Bits32 (opcode, 3, 0);
7675
7676                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7677                index = BitIsSet (opcode, 24);
7678                add = BitIsSet (opcode, 23);
7679                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7680
7681                // (shift_t, shift_n) = (SRType_LSL, 0);
7682                shift_t = SRType_LSL;
7683                shift_n = 0;
7684
7685                // if t == 15 || m == 15 then UNPREDICTABLE;
7686                if ((t == 15) || (m == 15))
7687                    return false;
7688
7689                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7690                if (wback && ((n == 15) || (n == t)))
7691                    return false;
7692
7693                break;
7694
7695            default:
7696                return false;
7697        }
7698
7699        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7700        if (!success)
7701            return false;
7702
7703        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7704        if (!success)
7705            return false;
7706
7707        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7708        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7709        if (!success)
7710            return false;
7711
7712        addr_t offset_addr;
7713        addr_t address;
7714
7715        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7716        if (add)
7717            offset_addr = Rn + offset;
7718        else
7719            offset_addr = Rn - offset;
7720
7721        // address = if index then offset_addr else R[n];
7722        if (index)
7723            address = offset_addr;
7724        else
7725            address = Rn;
7726
7727        // data = MemU[address,2];
7728        RegisterInfo base_reg;
7729        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7730
7731        RegisterInfo offset_reg;
7732        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7733
7734        EmulateInstruction::Context context;
7735        context.type = eContextRegisterLoad;
7736        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7737
7738        uint64_t data = MemURead (context, address, 2, 0, &success);
7739        if (!success)
7740            return false;
7741
7742        // if wback then R[n] = offset_addr;
7743        if (wback)
7744        {
7745            context.type = eContextAdjustBaseRegister;
7746            context.SetAddress (offset_addr);
7747            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7748                return false;
7749        }
7750
7751        // if UnalignedSupport() || address<0> = '0' then
7752        if (UnalignedSupport() || BitIsClear (address, 0))
7753        {
7754            // R[t] = SignExtend(data, 32);
7755            context.type = eContextRegisterLoad;
7756            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7757
7758            int64_t signed_data = llvm::SignExtend64<16>(data);
7759            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7760                return false;
7761        }
7762        else // Can only apply before ARMv7
7763        {
7764            // R[t] = bits(32) UNKNOWN;
7765            WriteBits32Unknown (t);
7766        }
7767    }
7768    return true;
7769}
7770
7771// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7772// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7773bool
7774EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7775{
7776#if 0
7777    if ConditionPassed() then
7778        EncodingSpecificOperations();
7779        rotated = ROR(R[m], rotation);
7780        R[d] = SignExtend(rotated<7:0>, 32);
7781#endif
7782
7783    bool success = false;
7784
7785    if (ConditionPassed(opcode))
7786    {
7787        uint32_t d;
7788        uint32_t m;
7789        uint32_t rotation;
7790
7791        // EncodingSpecificOperations();
7792        switch (encoding)
7793        {
7794            case eEncodingT1:
7795                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7796                d = Bits32 (opcode, 2, 0);
7797                m = Bits32 (opcode, 5, 3);
7798                rotation = 0;
7799
7800                break;
7801
7802            case eEncodingT2:
7803                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7804                d = Bits32 (opcode, 11, 8);
7805                m = Bits32 (opcode, 3, 0);
7806                rotation = Bits32 (opcode, 5, 4) << 3;
7807
7808                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7809                if (BadReg (d) || BadReg (m))
7810                    return false;
7811
7812                break;
7813
7814            case eEncodingA1:
7815                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7816                d = Bits32 (opcode, 15, 12);
7817                m = Bits32 (opcode, 3, 0);
7818                rotation = Bits32 (opcode, 11, 10) << 3;
7819
7820                // if d == 15 || m == 15 then UNPREDICTABLE;
7821                if ((d == 15) || (m == 15))
7822                    return false;
7823
7824                break;
7825
7826            default:
7827                return false;
7828        }
7829
7830        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7831        if (!success)
7832            return false;
7833
7834        // rotated = ROR(R[m], rotation);
7835        uint64_t rotated = ROR (Rm, rotation, &success);
7836        if (!success)
7837            return false;
7838
7839        // R[d] = SignExtend(rotated<7:0>, 32);
7840        int64_t data = llvm::SignExtend64<8>(rotated);
7841
7842        RegisterInfo source_reg;
7843        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7844
7845        EmulateInstruction::Context context;
7846        context.type = eContextRegisterLoad;
7847        context.SetRegister (source_reg);
7848
7849        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7850            return false;
7851    }
7852    return true;
7853}
7854
7855// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7856// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7857bool
7858EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7859{
7860#if 0
7861    if ConditionPassed() then
7862        EncodingSpecificOperations();
7863        rotated = ROR(R[m], rotation);
7864        R[d] = SignExtend(rotated<15:0>, 32);
7865#endif
7866
7867    bool success = false;
7868
7869    if (ConditionPassed(opcode))
7870    {
7871        uint32_t d;
7872        uint32_t m;
7873        uint32_t rotation;
7874
7875        // EncodingSpecificOperations();
7876        switch (encoding)
7877        {
7878            case eEncodingT1:
7879                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7880                d = Bits32 (opcode, 2, 0);
7881                m = Bits32 (opcode, 5, 3);
7882                rotation = 0;
7883
7884                break;
7885
7886            case eEncodingT2:
7887                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7888                d = Bits32 (opcode, 11, 8);
7889                m = Bits32 (opcode, 3, 0);
7890                rotation = Bits32 (opcode, 5, 4) << 3;
7891
7892                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7893                if (BadReg (d) || BadReg (m))
7894                    return false;
7895
7896                break;
7897
7898            case eEncodingA1:
7899                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7900                d = Bits32 (opcode, 15, 12);
7901                m = Bits32 (opcode, 3, 0);
7902                rotation = Bits32 (opcode, 11, 10) << 3;
7903
7904                // if d == 15 || m == 15 then UNPREDICTABLE;
7905                if ((d == 15) || (m == 15))
7906                    return false;
7907
7908                break;
7909
7910            default:
7911                return false;
7912        }
7913
7914        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7915        if (!success)
7916            return false;
7917
7918        // rotated = ROR(R[m], rotation);
7919        uint64_t rotated = ROR (Rm, rotation, &success);
7920        if (!success)
7921            return false;
7922
7923        // R[d] = SignExtend(rotated<15:0>, 32);
7924        RegisterInfo source_reg;
7925        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7926
7927        EmulateInstruction::Context context;
7928        context.type = eContextRegisterLoad;
7929        context.SetRegister (source_reg);
7930
7931        int64_t data = llvm::SignExtend64<16> (rotated);
7932        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7933            return false;
7934    }
7935
7936    return true;
7937}
7938
7939// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7940// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7941bool
7942EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7943{
7944#if 0
7945    if ConditionPassed() then
7946        EncodingSpecificOperations();
7947        rotated = ROR(R[m], rotation);
7948        R[d] = ZeroExtend(rotated<7:0>, 32);
7949#endif
7950
7951    bool success = false;
7952
7953    if (ConditionPassed(opcode))
7954    {
7955        uint32_t d;
7956        uint32_t m;
7957        uint32_t rotation;
7958
7959        // EncodingSpecificOperations();
7960        switch (encoding)
7961        {
7962            case eEncodingT1:
7963                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7964                d = Bits32 (opcode, 2, 0);
7965                m = Bits32 (opcode, 5, 3);
7966                rotation = 0;
7967
7968                break;
7969
7970            case eEncodingT2:
7971                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7972                d = Bits32 (opcode, 11, 8);
7973                m = Bits32 (opcode, 3, 0);
7974                  rotation = Bits32 (opcode, 5, 4) << 3;
7975
7976                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7977                if (BadReg (d) || BadReg (m))
7978                  return false;
7979
7980                break;
7981
7982            case eEncodingA1:
7983                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7984                d = Bits32 (opcode, 15, 12);
7985                m = Bits32 (opcode, 3, 0);
7986                rotation = Bits32 (opcode, 11, 10) << 3;
7987
7988                // if d == 15 || m == 15 then UNPREDICTABLE;
7989                if ((d == 15) || (m == 15))
7990                    return false;
7991
7992                break;
7993
7994            default:
7995                return false;
7996        }
7997
7998        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7999        if (!success)
8000            return false;
8001
8002        // rotated = ROR(R[m], rotation);
8003        uint64_t rotated = ROR (Rm, rotation, &success);
8004        if (!success)
8005            return false;
8006
8007        // R[d] = ZeroExtend(rotated<7:0>, 32);
8008        RegisterInfo source_reg;
8009        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8010
8011        EmulateInstruction::Context context;
8012        context.type = eContextRegisterLoad;
8013        context.SetRegister (source_reg);
8014
8015        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8016            return false;
8017    }
8018    return true;
8019}
8020
8021// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8022// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8023bool
8024EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8025{
8026#if 0
8027    if ConditionPassed() then
8028        EncodingSpecificOperations();
8029        rotated = ROR(R[m], rotation);
8030        R[d] = ZeroExtend(rotated<15:0>, 32);
8031#endif
8032
8033    bool success = false;
8034
8035    if (ConditionPassed(opcode))
8036    {
8037        uint32_t d;
8038        uint32_t m;
8039        uint32_t rotation;
8040
8041        switch (encoding)
8042        {
8043            case eEncodingT1:
8044                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8045                d = Bits32 (opcode, 2, 0);
8046                m = Bits32 (opcode, 5, 3);
8047                rotation = 0;
8048
8049                break;
8050
8051            case eEncodingT2:
8052                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8053                d = Bits32 (opcode, 11, 8);
8054                m = Bits32 (opcode, 3, 0);
8055                rotation = Bits32 (opcode, 5, 4) << 3;
8056
8057                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8058                if (BadReg (d) || BadReg (m))
8059                  return false;
8060
8061                break;
8062
8063            case eEncodingA1:
8064                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8065                d = Bits32 (opcode, 15, 12);
8066                m = Bits32 (opcode, 3, 0);
8067                rotation = Bits32 (opcode, 11, 10) << 3;
8068
8069                // if d == 15 || m == 15 then UNPREDICTABLE;
8070                if ((d == 15) || (m == 15))
8071                    return false;
8072
8073                break;
8074
8075            default:
8076                return false;
8077        }
8078
8079        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8080        if (!success)
8081            return false;
8082
8083        // rotated = ROR(R[m], rotation);
8084        uint64_t rotated = ROR (Rm, rotation, &success);
8085        if (!success)
8086            return false;
8087
8088        // R[d] = ZeroExtend(rotated<15:0>, 32);
8089        RegisterInfo source_reg;
8090        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8091
8092        EmulateInstruction::Context context;
8093        context.type = eContextRegisterLoad;
8094        context.SetRegister (source_reg);
8095
8096        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8097            return false;
8098    }
8099    return true;
8100}
8101
8102// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8103// word respectively.
8104bool
8105EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8106{
8107#if 0
8108    if ConditionPassed() then
8109        EncodingSpecificOperations();
8110        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8111            UNPREDICTABLE;
8112        else
8113            address = if increment then R[n] else R[n]-8;
8114            if wordhigher then address = address+4;
8115            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8116            BranchWritePC(MemA[address,4]);
8117            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8118#endif
8119
8120    bool success = false;
8121
8122    if (ConditionPassed(opcode))
8123    {
8124        uint32_t n;
8125        bool wback;
8126        bool increment;
8127        bool wordhigher;
8128
8129        // EncodingSpecificOperations();
8130        switch (encoding)
8131        {
8132            case eEncodingT1:
8133                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8134                n = Bits32 (opcode, 19, 16);
8135                wback = BitIsSet (opcode, 21);
8136                increment = false;
8137                wordhigher = false;
8138
8139                // if n == 15 then UNPREDICTABLE;
8140                if (n == 15)
8141                    return false;
8142
8143                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8144                if (InITBlock() && !LastInITBlock())
8145                    return false;
8146
8147                break;
8148
8149            case eEncodingT2:
8150                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8151                n = Bits32 (opcode, 19, 16);
8152                wback = BitIsSet (opcode, 21);
8153                increment = true;
8154                wordhigher = false;
8155
8156                // if n == 15 then UNPREDICTABLE;
8157                if (n == 15)
8158                    return false;
8159
8160                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8161                if (InITBlock() && !LastInITBlock())
8162                    return false;
8163
8164                break;
8165
8166            case eEncodingA1:
8167                // n = UInt(Rn);
8168                n = Bits32 (opcode, 19, 16);
8169
8170                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8171                wback = BitIsSet (opcode, 21);
8172                increment = BitIsSet (opcode, 23);
8173                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8174
8175                // if n == 15 then UNPREDICTABLE;
8176                if (n == 15)
8177                    return false;
8178
8179                break;
8180
8181            default:
8182                return false;
8183        }
8184
8185        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8186        if (!CurrentModeIsPrivileged ())
8187            // UNPREDICTABLE;
8188            return false;
8189        else
8190        {
8191            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8192            if (!success)
8193                return false;
8194
8195            addr_t address;
8196            // address = if increment then R[n] else R[n]-8;
8197            if (increment)
8198                address = Rn;
8199            else
8200                address = Rn - 8;
8201
8202            // if wordhigher then address = address+4;
8203            if (wordhigher)
8204                address = address + 4;
8205
8206            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8207            RegisterInfo base_reg;
8208            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8209
8210            EmulateInstruction::Context context;
8211            context.type = eContextReturnFromException;
8212            context.SetRegisterPlusOffset (base_reg, address - Rn);
8213
8214            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8215            if (!success)
8216                return false;
8217
8218            CPSRWriteByInstr (data, 15, true);
8219
8220            // BranchWritePC(MemA[address,4]);
8221            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8222            if (!success)
8223                return false;
8224
8225            BranchWritePC (context, data2);
8226
8227            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8228            if (wback)
8229            {
8230                context.type = eContextAdjustBaseRegister;
8231                if (increment)
8232                {
8233                    context.SetOffset (8);
8234                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8235                        return false;
8236                }
8237                else
8238                {
8239                    context.SetOffset (-8);
8240                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8241                        return false;
8242                }
8243            } // if wback
8244        }
8245    } // if ConditionPassed()
8246    return true;
8247}
8248
8249// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8250// and writes the result to the destination register.  It can optionally update the condition flags based on
8251// the result.
8252bool
8253EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8254{
8255#if 0
8256    // ARM pseudo code...
8257    if ConditionPassed() then
8258        EncodingSpecificOperations();
8259        result = R[n] EOR imm32;
8260        if d == 15 then         // Can only occur for ARM encoding
8261            ALUWritePC(result); // setflags is always FALSE here
8262        else
8263            R[d] = result;
8264            if setflags then
8265                APSR.N = result<31>;
8266                APSR.Z = IsZeroBit(result);
8267                APSR.C = carry;
8268                // APSR.V unchanged
8269#endif
8270
8271    bool success = false;
8272
8273    if (ConditionPassed(opcode))
8274    {
8275        uint32_t Rd, Rn;
8276        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8277        bool setflags;
8278        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8279        switch (encoding)
8280        {
8281        case eEncodingT1:
8282            Rd = Bits32(opcode, 11, 8);
8283            Rn = Bits32(opcode, 19, 16);
8284            setflags = BitIsSet(opcode, 20);
8285            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8286            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8287            if (Rd == 15 && setflags)
8288                return EmulateTEQImm (opcode, eEncodingT1);
8289            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8290                return false;
8291            break;
8292        case eEncodingA1:
8293            Rd = Bits32(opcode, 15, 12);
8294            Rn = Bits32(opcode, 19, 16);
8295            setflags = BitIsSet(opcode, 20);
8296            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8297
8298            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8299            if (Rd == 15 && setflags)
8300                return EmulateSUBSPcLrEtc (opcode, encoding);
8301            break;
8302        default:
8303            return false;
8304        }
8305
8306        // Read the first operand.
8307        uint32_t val1 = ReadCoreReg(Rn, &success);
8308        if (!success)
8309            return false;
8310
8311        uint32_t result = val1 ^ imm32;
8312
8313        EmulateInstruction::Context context;
8314        context.type = EmulateInstruction::eContextImmediate;
8315        context.SetNoArgs ();
8316
8317        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8318            return false;
8319    }
8320    return true;
8321}
8322
8323// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8324// optionally-shifted register value, and writes the result to the destination register.
8325// It can optionally update the condition flags based on the result.
8326bool
8327EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8328{
8329#if 0
8330    // ARM pseudo code...
8331    if ConditionPassed() then
8332        EncodingSpecificOperations();
8333        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8334        result = R[n] EOR shifted;
8335        if d == 15 then         // Can only occur for ARM encoding
8336            ALUWritePC(result); // setflags is always FALSE here
8337        else
8338            R[d] = result;
8339            if setflags then
8340                APSR.N = result<31>;
8341                APSR.Z = IsZeroBit(result);
8342                APSR.C = carry;
8343                // APSR.V unchanged
8344#endif
8345
8346    bool success = false;
8347
8348    if (ConditionPassed(opcode))
8349    {
8350        uint32_t Rd, Rn, Rm;
8351        ARM_ShifterType shift_t;
8352        uint32_t shift_n; // the shift applied to the value read from Rm
8353        bool setflags;
8354        uint32_t carry;
8355        switch (encoding)
8356        {
8357        case eEncodingT1:
8358            Rd = Rn = Bits32(opcode, 2, 0);
8359            Rm = Bits32(opcode, 5, 3);
8360            setflags = !InITBlock();
8361            shift_t = SRType_LSL;
8362            shift_n = 0;
8363            break;
8364        case eEncodingT2:
8365            Rd = Bits32(opcode, 11, 8);
8366            Rn = Bits32(opcode, 19, 16);
8367            Rm = Bits32(opcode, 3, 0);
8368            setflags = BitIsSet(opcode, 20);
8369            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8370            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8371            if (Rd == 15 && setflags)
8372                return EmulateTEQReg (opcode, eEncodingT1);
8373            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8374                return false;
8375            break;
8376        case eEncodingA1:
8377            Rd = Bits32(opcode, 15, 12);
8378            Rn = Bits32(opcode, 19, 16);
8379            Rm = Bits32(opcode, 3, 0);
8380            setflags = BitIsSet(opcode, 20);
8381            shift_n = DecodeImmShiftARM(opcode, shift_t);
8382
8383            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8384            if (Rd == 15 && setflags)
8385                return EmulateSUBSPcLrEtc (opcode, encoding);
8386            break;
8387        default:
8388            return false;
8389        }
8390
8391        // Read the first operand.
8392        uint32_t val1 = ReadCoreReg(Rn, &success);
8393        if (!success)
8394            return false;
8395
8396        // Read the second operand.
8397        uint32_t val2 = ReadCoreReg(Rm, &success);
8398        if (!success)
8399            return false;
8400
8401        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8402        if (!success)
8403            return false;
8404        uint32_t result = val1 ^ shifted;
8405
8406        EmulateInstruction::Context context;
8407        context.type = EmulateInstruction::eContextImmediate;
8408        context.SetNoArgs ();
8409
8410        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8411            return false;
8412    }
8413    return true;
8414}
8415
8416// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8417// writes the result to the destination register.  It can optionally update the condition flags based
8418// on the result.
8419bool
8420EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8421{
8422#if 0
8423    // ARM pseudo code...
8424    if ConditionPassed() then
8425        EncodingSpecificOperations();
8426        result = R[n] OR imm32;
8427        if d == 15 then         // Can only occur for ARM encoding
8428            ALUWritePC(result); // setflags is always FALSE here
8429        else
8430            R[d] = result;
8431            if setflags then
8432                APSR.N = result<31>;
8433                APSR.Z = IsZeroBit(result);
8434                APSR.C = carry;
8435                // APSR.V unchanged
8436#endif
8437
8438    bool success = false;
8439
8440    if (ConditionPassed(opcode))
8441    {
8442        uint32_t Rd, Rn;
8443        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8444        bool setflags;
8445        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8446        switch (encoding)
8447        {
8448        case eEncodingT1:
8449            Rd = Bits32(opcode, 11, 8);
8450            Rn = Bits32(opcode, 19, 16);
8451            setflags = BitIsSet(opcode, 20);
8452            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8453            // if Rn == '1111' then SEE MOV (immediate);
8454            if (Rn == 15)
8455                return EmulateMOVRdImm (opcode, eEncodingT2);
8456            if (BadReg(Rd) || Rn == 13)
8457                return false;
8458            break;
8459        case eEncodingA1:
8460            Rd = Bits32(opcode, 15, 12);
8461            Rn = Bits32(opcode, 19, 16);
8462            setflags = BitIsSet(opcode, 20);
8463            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8464
8465            if (Rd == 15 && setflags)
8466                return EmulateSUBSPcLrEtc (opcode, encoding);
8467            break;
8468        default:
8469            return false;
8470        }
8471
8472        // Read the first operand.
8473        uint32_t val1 = ReadCoreReg(Rn, &success);
8474        if (!success)
8475            return false;
8476
8477        uint32_t result = val1 | imm32;
8478
8479        EmulateInstruction::Context context;
8480        context.type = EmulateInstruction::eContextImmediate;
8481        context.SetNoArgs ();
8482
8483        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8484            return false;
8485    }
8486    return true;
8487}
8488
8489// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8490// value, and writes the result to the destination register.  It can optionally update the condition flags based
8491// on the result.
8492bool
8493EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8494{
8495#if 0
8496    // ARM pseudo code...
8497    if ConditionPassed() then
8498        EncodingSpecificOperations();
8499        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8500        result = R[n] OR shifted;
8501        if d == 15 then         // Can only occur for ARM encoding
8502            ALUWritePC(result); // setflags is always FALSE here
8503        else
8504            R[d] = result;
8505            if setflags then
8506                APSR.N = result<31>;
8507                APSR.Z = IsZeroBit(result);
8508                APSR.C = carry;
8509                // APSR.V unchanged
8510#endif
8511
8512    bool success = false;
8513
8514    if (ConditionPassed(opcode))
8515    {
8516        uint32_t Rd, Rn, Rm;
8517        ARM_ShifterType shift_t;
8518        uint32_t shift_n; // the shift applied to the value read from Rm
8519        bool setflags;
8520        uint32_t carry;
8521        switch (encoding)
8522        {
8523        case eEncodingT1:
8524            Rd = Rn = Bits32(opcode, 2, 0);
8525            Rm = Bits32(opcode, 5, 3);
8526            setflags = !InITBlock();
8527            shift_t = SRType_LSL;
8528            shift_n = 0;
8529            break;
8530        case eEncodingT2:
8531            Rd = Bits32(opcode, 11, 8);
8532            Rn = Bits32(opcode, 19, 16);
8533            Rm = Bits32(opcode, 3, 0);
8534            setflags = BitIsSet(opcode, 20);
8535            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8536            // if Rn == '1111' then SEE MOV (register);
8537            if (Rn == 15)
8538                return EmulateMOVRdRm (opcode, eEncodingT3);
8539            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8540                return false;
8541            break;
8542        case eEncodingA1:
8543            Rd = Bits32(opcode, 15, 12);
8544            Rn = Bits32(opcode, 19, 16);
8545            Rm = Bits32(opcode, 3, 0);
8546            setflags = BitIsSet(opcode, 20);
8547            shift_n = DecodeImmShiftARM(opcode, shift_t);
8548
8549            if (Rd == 15 && setflags)
8550                return EmulateSUBSPcLrEtc (opcode, encoding);
8551            break;
8552        default:
8553            return false;
8554        }
8555
8556        // Read the first operand.
8557        uint32_t val1 = ReadCoreReg(Rn, &success);
8558        if (!success)
8559            return false;
8560
8561        // Read the second operand.
8562        uint32_t val2 = ReadCoreReg(Rm, &success);
8563        if (!success)
8564            return false;
8565
8566        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8567        if (!success)
8568            return false;
8569        uint32_t result = val1 | shifted;
8570
8571        EmulateInstruction::Context context;
8572        context.type = EmulateInstruction::eContextImmediate;
8573        context.SetNoArgs ();
8574
8575        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8576            return false;
8577    }
8578    return true;
8579}
8580
8581// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8582// the destination register. It can optionally update the condition flags based on the result.
8583bool
8584EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8585{
8586#if 0
8587    // ARM pseudo code...
8588    if ConditionPassed() then
8589        EncodingSpecificOperations();
8590        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8591        if d == 15 then         // Can only occur for ARM encoding
8592            ALUWritePC(result); // setflags is always FALSE here
8593        else
8594            R[d] = result;
8595            if setflags then
8596                APSR.N = result<31>;
8597                APSR.Z = IsZeroBit(result);
8598                APSR.C = carry;
8599                APSR.V = overflow;
8600#endif
8601
8602    bool success = false;
8603
8604    uint32_t Rd; // the destination register
8605    uint32_t Rn; // the first operand
8606    bool setflags;
8607    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8608    switch (encoding) {
8609    case eEncodingT1:
8610        Rd = Bits32(opcode, 2, 0);
8611        Rn = Bits32(opcode, 5, 3);
8612        setflags = !InITBlock();
8613        imm32 = 0;
8614        break;
8615    case eEncodingT2:
8616        Rd = Bits32(opcode, 11, 8);
8617        Rn = Bits32(opcode, 19, 16);
8618        setflags = BitIsSet(opcode, 20);
8619        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8620        if (BadReg(Rd) || BadReg(Rn))
8621            return false;
8622        break;
8623    case eEncodingA1:
8624        Rd = Bits32(opcode, 15, 12);
8625        Rn = Bits32(opcode, 19, 16);
8626        setflags = BitIsSet(opcode, 20);
8627        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8628
8629        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8630        if (Rd == 15 && setflags)
8631            return EmulateSUBSPcLrEtc (opcode, encoding);
8632        break;
8633    default:
8634        return false;
8635    }
8636    // Read the register value from the operand register Rn.
8637    uint32_t reg_val = ReadCoreReg(Rn, &success);
8638    if (!success)
8639        return false;
8640
8641    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8642
8643    EmulateInstruction::Context context;
8644    context.type = EmulateInstruction::eContextImmediate;
8645    context.SetNoArgs ();
8646
8647    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8648        return false;
8649
8650    return true;
8651}
8652
8653// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8654// result to the destination register. It can optionally update the condition flags based on the result.
8655bool
8656EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8657{
8658#if 0
8659    // ARM pseudo code...
8660    if ConditionPassed() then
8661        EncodingSpecificOperations();
8662        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8663        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8664        if d == 15 then         // Can only occur for ARM encoding
8665            ALUWritePC(result); // setflags is always FALSE here
8666        else
8667            R[d] = result;
8668            if setflags then
8669                APSR.N = result<31>;
8670                APSR.Z = IsZeroBit(result);
8671                APSR.C = carry;
8672                APSR.V = overflow;
8673#endif
8674
8675    bool success = false;
8676
8677    uint32_t Rd; // the destination register
8678    uint32_t Rn; // the first operand
8679    uint32_t Rm; // the second operand
8680    bool setflags;
8681    ARM_ShifterType shift_t;
8682    uint32_t shift_n; // the shift applied to the value read from Rm
8683    switch (encoding) {
8684    case eEncodingT1:
8685        Rd = Bits32(opcode, 11, 8);
8686        Rn = Bits32(opcode, 19, 16);
8687        Rm = Bits32(opcode, 3, 0);
8688        setflags = BitIsSet(opcode, 20);
8689        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8690        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8691        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8692            return false;
8693        break;
8694    case eEncodingA1:
8695        Rd = Bits32(opcode, 15, 12);
8696        Rn = Bits32(opcode, 19, 16);
8697        Rm = Bits32(opcode, 3, 0);
8698        setflags = BitIsSet(opcode, 20);
8699        shift_n = DecodeImmShiftARM(opcode, shift_t);
8700
8701        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8702        if (Rd == 15 && setflags)
8703            return EmulateSUBSPcLrEtc (opcode, encoding);
8704        break;
8705    default:
8706        return false;
8707    }
8708    // Read the register value from register Rn.
8709    uint32_t val1 = ReadCoreReg(Rn, &success);
8710    if (!success)
8711        return false;
8712
8713    // Read the register value from register Rm.
8714    uint32_t val2 = ReadCoreReg(Rm, &success);
8715    if (!success)
8716        return false;
8717
8718    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8719    if (!success)
8720        return false;
8721    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8722
8723    EmulateInstruction::Context context;
8724    context.type = EmulateInstruction::eContextImmediate;
8725    context.SetNoArgs();
8726    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8727        return false;
8728
8729    return true;
8730}
8731
8732// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8733// an immediate value, and writes the result to the destination register. It can optionally update the condition
8734// flags based on the result.
8735bool
8736EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8737{
8738#if 0
8739    // ARM pseudo code...
8740    if ConditionPassed() then
8741        EncodingSpecificOperations();
8742        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8743        if d == 15 then
8744            ALUWritePC(result); // setflags is always FALSE here
8745        else
8746            R[d] = result;
8747            if setflags then
8748                APSR.N = result<31>;
8749                APSR.Z = IsZeroBit(result);
8750                APSR.C = carry;
8751                APSR.V = overflow;
8752#endif
8753
8754    bool success = false;
8755
8756    uint32_t Rd; // the destination register
8757    uint32_t Rn; // the first operand
8758    bool setflags;
8759    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8760    switch (encoding) {
8761    case eEncodingA1:
8762        Rd = Bits32(opcode, 15, 12);
8763        Rn = Bits32(opcode, 19, 16);
8764        setflags = BitIsSet(opcode, 20);
8765        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8766
8767        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8768        if (Rd == 15 && setflags)
8769            return EmulateSUBSPcLrEtc  (opcode, encoding);
8770        break;
8771    default:
8772        return false;
8773    }
8774    // Read the register value from the operand register Rn.
8775    uint32_t reg_val = ReadCoreReg(Rn, &success);
8776    if (!success)
8777        return false;
8778
8779    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8780
8781    EmulateInstruction::Context context;
8782    context.type = EmulateInstruction::eContextImmediate;
8783    context.SetNoArgs ();
8784
8785    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8786        return false;
8787
8788    return true;
8789}
8790
8791// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8792// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8793// condition flags based on the result.
8794bool
8795EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8796{
8797#if 0
8798    // ARM pseudo code...
8799    if ConditionPassed() then
8800        EncodingSpecificOperations();
8801        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8802        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8803        if d == 15 then
8804            ALUWritePC(result); // setflags is always FALSE here
8805        else
8806            R[d] = result;
8807            if setflags then
8808                APSR.N = result<31>;
8809                APSR.Z = IsZeroBit(result);
8810                APSR.C = carry;
8811                APSR.V = overflow;
8812#endif
8813
8814    bool success = false;
8815
8816    uint32_t Rd; // the destination register
8817    uint32_t Rn; // the first operand
8818    uint32_t Rm; // the second operand
8819    bool setflags;
8820    ARM_ShifterType shift_t;
8821    uint32_t shift_n; // the shift applied to the value read from Rm
8822    switch (encoding) {
8823    case eEncodingA1:
8824        Rd = Bits32(opcode, 15, 12);
8825        Rn = Bits32(opcode, 19, 16);
8826        Rm = Bits32(opcode, 3, 0);
8827        setflags = BitIsSet(opcode, 20);
8828        shift_n = DecodeImmShiftARM(opcode, shift_t);
8829
8830        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8831        if (Rd == 15 && setflags)
8832            return EmulateSUBSPcLrEtc (opcode, encoding);
8833        break;
8834    default:
8835        return false;
8836    }
8837    // Read the register value from register Rn.
8838    uint32_t val1 = ReadCoreReg(Rn, &success);
8839    if (!success)
8840        return false;
8841
8842    // Read the register value from register Rm.
8843    uint32_t val2 = ReadCoreReg(Rm, &success);
8844    if (!success)
8845        return false;
8846
8847    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8848    if (!success)
8849        return false;
8850    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8851
8852    EmulateInstruction::Context context;
8853    context.type = EmulateInstruction::eContextImmediate;
8854    context.SetNoArgs();
8855    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8856        return false;
8857
8858    return true;
8859}
8860
8861// Subtract with Carry (immediate) subtracts an immediate value and the value of
8862// NOT (Carry flag) from a register value, and writes the result to the destination register.
8863// It can optionally update the condition flags based on the result.
8864bool
8865EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8866{
8867#if 0
8868    // ARM pseudo code...
8869    if ConditionPassed() then
8870        EncodingSpecificOperations();
8871        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8872        if d == 15 then         // Can only occur for ARM encoding
8873            ALUWritePC(result); // setflags is always FALSE here
8874        else
8875            R[d] = result;
8876            if setflags then
8877                APSR.N = result<31>;
8878                APSR.Z = IsZeroBit(result);
8879                APSR.C = carry;
8880                APSR.V = overflow;
8881#endif
8882
8883    bool success = false;
8884
8885    uint32_t Rd; // the destination register
8886    uint32_t Rn; // the first operand
8887    bool setflags;
8888    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8889    switch (encoding) {
8890    case eEncodingT1:
8891        Rd = Bits32(opcode, 11, 8);
8892        Rn = Bits32(opcode, 19, 16);
8893        setflags = BitIsSet(opcode, 20);
8894        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8895        if (BadReg(Rd) || BadReg(Rn))
8896            return false;
8897        break;
8898    case eEncodingA1:
8899        Rd = Bits32(opcode, 15, 12);
8900        Rn = Bits32(opcode, 19, 16);
8901        setflags = BitIsSet(opcode, 20);
8902        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8903
8904        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8905        if (Rd == 15 && setflags)
8906            return EmulateSUBSPcLrEtc (opcode, encoding);
8907        break;
8908    default:
8909        return false;
8910    }
8911    // Read the register value from the operand register Rn.
8912    uint32_t reg_val = ReadCoreReg(Rn, &success);
8913    if (!success)
8914        return false;
8915
8916    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8917
8918    EmulateInstruction::Context context;
8919    context.type = EmulateInstruction::eContextImmediate;
8920    context.SetNoArgs ();
8921
8922    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8923        return false;
8924
8925    return true;
8926}
8927
8928// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8929// NOT (Carry flag) from a register value, and writes the result to the destination register.
8930// It can optionally update the condition flags based on the result.
8931bool
8932EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8933{
8934#if 0
8935    // ARM pseudo code...
8936    if ConditionPassed() then
8937        EncodingSpecificOperations();
8938        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8939        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8940        if d == 15 then         // Can only occur for ARM encoding
8941            ALUWritePC(result); // setflags is always FALSE here
8942        else
8943            R[d] = result;
8944            if setflags then
8945                APSR.N = result<31>;
8946                APSR.Z = IsZeroBit(result);
8947                APSR.C = carry;
8948                APSR.V = overflow;
8949#endif
8950
8951    bool success = false;
8952
8953    uint32_t Rd; // the destination register
8954    uint32_t Rn; // the first operand
8955    uint32_t Rm; // the second operand
8956    bool setflags;
8957    ARM_ShifterType shift_t;
8958    uint32_t shift_n; // the shift applied to the value read from Rm
8959    switch (encoding) {
8960    case eEncodingT1:
8961        Rd = Rn = Bits32(opcode, 2, 0);
8962        Rm = Bits32(opcode, 5, 3);
8963        setflags = !InITBlock();
8964        shift_t = SRType_LSL;
8965        shift_n = 0;
8966        break;
8967    case eEncodingT2:
8968        Rd = Bits32(opcode, 11, 8);
8969        Rn = Bits32(opcode, 19, 16);
8970        Rm = Bits32(opcode, 3, 0);
8971        setflags = BitIsSet(opcode, 20);
8972        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8973        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8974            return false;
8975        break;
8976    case eEncodingA1:
8977        Rd = Bits32(opcode, 15, 12);
8978        Rn = Bits32(opcode, 19, 16);
8979        Rm = Bits32(opcode, 3, 0);
8980        setflags = BitIsSet(opcode, 20);
8981        shift_n = DecodeImmShiftARM(opcode, shift_t);
8982
8983        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8984        if (Rd == 15 && setflags)
8985            return EmulateSUBSPcLrEtc (opcode, encoding);
8986        break;
8987    default:
8988        return false;
8989    }
8990    // Read the register value from register Rn.
8991    uint32_t val1 = ReadCoreReg(Rn, &success);
8992    if (!success)
8993        return false;
8994
8995    // Read the register value from register Rm.
8996    uint32_t val2 = ReadCoreReg(Rm, &success);
8997    if (!success)
8998        return false;
8999
9000    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9001    if (!success)
9002        return false;
9003    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9004
9005    EmulateInstruction::Context context;
9006    context.type = EmulateInstruction::eContextImmediate;
9007    context.SetNoArgs();
9008    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9009        return false;
9010
9011    return true;
9012}
9013
9014// This instruction subtracts an immediate value from a register value, and writes the result
9015// to the destination register.  It can optionally update the condition flags based on the result.
9016bool
9017EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9018{
9019#if 0
9020    // ARM pseudo code...
9021    if ConditionPassed() then
9022        EncodingSpecificOperations();
9023        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9024        R[d] = result;
9025        if setflags then
9026            APSR.N = result<31>;
9027            APSR.Z = IsZeroBit(result);
9028            APSR.C = carry;
9029            APSR.V = overflow;
9030#endif
9031
9032    bool success = false;
9033
9034    uint32_t Rd; // the destination register
9035    uint32_t Rn; // the first operand
9036    bool setflags;
9037    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9038    switch (encoding) {
9039    case eEncodingT1:
9040        Rd = Bits32(opcode, 2, 0);
9041        Rn = Bits32(opcode, 5, 3);
9042        setflags = !InITBlock();
9043        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9044        break;
9045    case eEncodingT2:
9046        Rd = Rn = Bits32(opcode, 10, 8);
9047        setflags = !InITBlock();
9048        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9049        break;
9050    case eEncodingT3:
9051        Rd = Bits32(opcode, 11, 8);
9052        Rn = Bits32(opcode, 19, 16);
9053        setflags = BitIsSet(opcode, 20);
9054        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9055
9056        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9057        if (Rd == 15 && setflags)
9058            return EmulateCMPImm (opcode, eEncodingT2);
9059
9060        // if Rn == '1101' then SEE SUB (SP minus immediate);
9061        if (Rn == 13)
9062            return EmulateSUBSPImm (opcode, eEncodingT2);
9063
9064        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9065        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9066            return false;
9067        break;
9068    case eEncodingT4:
9069        Rd = Bits32(opcode, 11, 8);
9070        Rn = Bits32(opcode, 19, 16);
9071        setflags = BitIsSet(opcode, 20);
9072        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9073
9074        // if Rn == '1111' then SEE ADR;
9075        if (Rn == 15)
9076            return EmulateADR (opcode, eEncodingT2);
9077
9078        // if Rn == '1101' then SEE SUB (SP minus immediate);
9079        if (Rn == 13)
9080            return EmulateSUBSPImm (opcode, eEncodingT3);
9081
9082        if (BadReg(Rd))
9083            return false;
9084        break;
9085    default:
9086        return false;
9087    }
9088    // Read the register value from the operand register Rn.
9089    uint32_t reg_val = ReadCoreReg(Rn, &success);
9090    if (!success)
9091        return false;
9092
9093    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9094
9095    EmulateInstruction::Context context;
9096    context.type = EmulateInstruction::eContextImmediate;
9097    context.SetNoArgs ();
9098
9099    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9100        return false;
9101
9102    return true;
9103}
9104
9105// This instruction subtracts an immediate value from a register value, and writes the result
9106// to the destination register.  It can optionally update the condition flags based on the result.
9107bool
9108EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9109{
9110#if 0
9111    // ARM pseudo code...
9112    if ConditionPassed() then
9113        EncodingSpecificOperations();
9114        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9115        if d == 15 then
9116            ALUWritePC(result); // setflags is always FALSE here
9117        else
9118            R[d] = result;
9119            if setflags then
9120                APSR.N = result<31>;
9121                APSR.Z = IsZeroBit(result);
9122                APSR.C = carry;
9123                APSR.V = overflow;
9124#endif
9125
9126    bool success = false;
9127
9128    uint32_t Rd; // the destination register
9129    uint32_t Rn; // the first operand
9130    bool setflags;
9131    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9132    switch (encoding) {
9133    case eEncodingA1:
9134        Rd = Bits32(opcode, 15, 12);
9135        Rn = Bits32(opcode, 19, 16);
9136        setflags = BitIsSet(opcode, 20);
9137        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9138
9139        // if Rn == '1111' && S == '0' then SEE ADR;
9140        if (Rn == 15 && !setflags)
9141            return EmulateADR (opcode, eEncodingA2);
9142
9143        // if Rn == '1101' then SEE SUB (SP minus immediate);
9144        if (Rn == 13)
9145            return EmulateSUBSPImm (opcode, eEncodingA1);
9146
9147        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9148        if (Rd == 15 && setflags)
9149            return EmulateSUBSPcLrEtc (opcode, encoding);
9150        break;
9151    default:
9152        return false;
9153    }
9154    // Read the register value from the operand register Rn.
9155    uint32_t reg_val = ReadCoreReg(Rn, &success);
9156    if (!success)
9157        return false;
9158
9159    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9160
9161    EmulateInstruction::Context context;
9162    context.type = EmulateInstruction::eContextImmediate;
9163    context.SetNoArgs ();
9164
9165    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9166        return false;
9167
9168    return true;
9169}
9170
9171// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9172// immediate value.  It updates the condition flags based on the result, and discards the result.
9173bool
9174EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9175{
9176#if 0
9177    // ARM pseudo code...
9178    if ConditionPassed() then
9179        EncodingSpecificOperations();
9180        result = R[n] EOR imm32;
9181        APSR.N = result<31>;
9182        APSR.Z = IsZeroBit(result);
9183        APSR.C = carry;
9184        // APSR.V unchanged
9185#endif
9186
9187    bool success = false;
9188
9189    if (ConditionPassed(opcode))
9190    {
9191        uint32_t Rn;
9192        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9193        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9194        switch (encoding)
9195        {
9196        case eEncodingT1:
9197            Rn = Bits32(opcode, 19, 16);
9198            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9199            if (BadReg(Rn))
9200                return false;
9201            break;
9202        case eEncodingA1:
9203            Rn = Bits32(opcode, 19, 16);
9204            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9205            break;
9206        default:
9207            return false;
9208        }
9209
9210        // Read the first operand.
9211        uint32_t val1 = ReadCoreReg(Rn, &success);
9212        if (!success)
9213            return false;
9214
9215        uint32_t result = val1 ^ imm32;
9216
9217        EmulateInstruction::Context context;
9218        context.type = EmulateInstruction::eContextImmediate;
9219        context.SetNoArgs ();
9220
9221        if (!WriteFlags(context, result, carry))
9222            return false;
9223    }
9224    return true;
9225}
9226
9227// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9228// optionally-shifted register value.  It updates the condition flags based on the result, and discards
9229// the result.
9230bool
9231EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9232{
9233#if 0
9234    // ARM pseudo code...
9235    if ConditionPassed() then
9236        EncodingSpecificOperations();
9237        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9238        result = R[n] EOR shifted;
9239        APSR.N = result<31>;
9240        APSR.Z = IsZeroBit(result);
9241        APSR.C = carry;
9242        // APSR.V unchanged
9243#endif
9244
9245    bool success = false;
9246
9247    if (ConditionPassed(opcode))
9248    {
9249        uint32_t Rn, Rm;
9250        ARM_ShifterType shift_t;
9251        uint32_t shift_n; // the shift applied to the value read from Rm
9252        uint32_t carry;
9253        switch (encoding)
9254        {
9255        case eEncodingT1:
9256            Rn = Bits32(opcode, 19, 16);
9257            Rm = Bits32(opcode, 3, 0);
9258            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9259            if (BadReg(Rn) || BadReg(Rm))
9260                return false;
9261            break;
9262        case eEncodingA1:
9263            Rn = Bits32(opcode, 19, 16);
9264            Rm = Bits32(opcode, 3, 0);
9265            shift_n = DecodeImmShiftARM(opcode, shift_t);
9266            break;
9267        default:
9268            return false;
9269        }
9270
9271        // Read the first operand.
9272        uint32_t val1 = ReadCoreReg(Rn, &success);
9273        if (!success)
9274            return false;
9275
9276        // Read the second operand.
9277        uint32_t val2 = ReadCoreReg(Rm, &success);
9278        if (!success)
9279            return false;
9280
9281        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9282        if (!success)
9283            return false;
9284        uint32_t result = val1 ^ shifted;
9285
9286        EmulateInstruction::Context context;
9287        context.type = EmulateInstruction::eContextImmediate;
9288        context.SetNoArgs ();
9289
9290        if (!WriteFlags(context, result, carry))
9291            return false;
9292    }
9293    return true;
9294}
9295
9296// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9297// It updates the condition flags based on the result, and discards the result.
9298bool
9299EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9300{
9301#if 0
9302    // ARM pseudo code...
9303    if ConditionPassed() then
9304        EncodingSpecificOperations();
9305        result = R[n] AND imm32;
9306        APSR.N = result<31>;
9307        APSR.Z = IsZeroBit(result);
9308        APSR.C = carry;
9309        // APSR.V unchanged
9310#endif
9311
9312    bool success = false;
9313
9314    if (ConditionPassed(opcode))
9315    {
9316        uint32_t Rn;
9317        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9318        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9319        switch (encoding)
9320        {
9321        case eEncodingT1:
9322            Rn = Bits32(opcode, 19, 16);
9323            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9324            if (BadReg(Rn))
9325                return false;
9326            break;
9327        case eEncodingA1:
9328            Rn = Bits32(opcode, 19, 16);
9329            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9330            break;
9331        default:
9332            return false;
9333        }
9334
9335        // Read the first operand.
9336        uint32_t val1 = ReadCoreReg(Rn, &success);
9337        if (!success)
9338            return false;
9339
9340        uint32_t result = val1 & imm32;
9341
9342        EmulateInstruction::Context context;
9343        context.type = EmulateInstruction::eContextImmediate;
9344        context.SetNoArgs ();
9345
9346        if (!WriteFlags(context, result, carry))
9347            return false;
9348    }
9349    return true;
9350}
9351
9352// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9353// It updates the condition flags based on the result, and discards the result.
9354bool
9355EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9356{
9357#if 0
9358    // ARM pseudo code...
9359    if ConditionPassed() then
9360        EncodingSpecificOperations();
9361        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9362        result = R[n] AND shifted;
9363        APSR.N = result<31>;
9364        APSR.Z = IsZeroBit(result);
9365        APSR.C = carry;
9366        // APSR.V unchanged
9367#endif
9368
9369    bool success = false;
9370
9371    if (ConditionPassed(opcode))
9372    {
9373        uint32_t Rn, Rm;
9374        ARM_ShifterType shift_t;
9375        uint32_t shift_n; // the shift applied to the value read from Rm
9376        uint32_t carry;
9377        switch (encoding)
9378        {
9379        case eEncodingT1:
9380            Rn = Bits32(opcode, 2, 0);
9381            Rm = Bits32(opcode, 5, 3);
9382            shift_t = SRType_LSL;
9383            shift_n = 0;
9384            break;
9385        case eEncodingT2:
9386            Rn = Bits32(opcode, 19, 16);
9387            Rm = Bits32(opcode, 3, 0);
9388            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9389            if (BadReg(Rn) || BadReg(Rm))
9390                return false;
9391            break;
9392        case eEncodingA1:
9393            Rn = Bits32(opcode, 19, 16);
9394            Rm = Bits32(opcode, 3, 0);
9395            shift_n = DecodeImmShiftARM(opcode, shift_t);
9396            break;
9397        default:
9398            return false;
9399        }
9400
9401        // Read the first operand.
9402        uint32_t val1 = ReadCoreReg(Rn, &success);
9403        if (!success)
9404            return false;
9405
9406        // Read the second operand.
9407        uint32_t val2 = ReadCoreReg(Rm, &success);
9408        if (!success)
9409            return false;
9410
9411        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9412        if (!success)
9413            return false;
9414        uint32_t result = val1 & shifted;
9415
9416        EmulateInstruction::Context context;
9417        context.type = EmulateInstruction::eContextImmediate;
9418        context.SetNoArgs ();
9419
9420        if (!WriteFlags(context, result, carry))
9421            return false;
9422    }
9423    return true;
9424}
9425
9426// A8.6.216 SUB (SP minus register)
9427bool
9428EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9429{
9430#if 0
9431    if ConditionPassed() then
9432        EncodingSpecificOperations();
9433        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9434        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9435        if d == 15 then // Can only occur for ARM encoding
9436            ALUWritePC(result); // setflags is always FALSE here
9437        else
9438            R[d] = result;
9439            if setflags then
9440                APSR.N = result<31>;
9441                APSR.Z = IsZeroBit(result);
9442                APSR.C = carry;
9443                APSR.V = overflow;
9444#endif
9445
9446    bool success = false;
9447
9448    if (ConditionPassed(opcode))
9449    {
9450        uint32_t d;
9451        uint32_t m;
9452        bool setflags;
9453        ARM_ShifterType shift_t;
9454        uint32_t shift_n;
9455
9456        switch (encoding)
9457        {
9458            case eEncodingT1:
9459                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9460                d = Bits32 (opcode, 11, 8);
9461                m = Bits32 (opcode, 3, 0);
9462                setflags = BitIsSet (opcode, 20);
9463
9464                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9465                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9466
9467                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9468                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9469                    return false;
9470
9471                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9472                if ((d == 15) || BadReg (m))
9473                    return false;
9474                break;
9475
9476            case eEncodingA1:
9477                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9478                d = Bits32 (opcode, 15, 12);
9479                m = Bits32 (opcode, 3, 0);
9480                setflags = BitIsSet (opcode, 20);
9481
9482                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9483                if (d == 15 && setflags)
9484                    EmulateSUBSPcLrEtc (opcode, encoding);
9485
9486                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9487                shift_n = DecodeImmShiftARM (opcode, shift_t);
9488                break;
9489
9490            default:
9491                return false;
9492        }
9493
9494        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9495        uint32_t Rm = ReadCoreReg (m, &success);
9496        if (!success)
9497            return false;
9498
9499        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9500        if (!success)
9501            return false;
9502
9503        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9504        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9505        if (!success)
9506            return false;
9507
9508        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9509
9510        EmulateInstruction::Context context;
9511        context.type = eContextArithmetic;
9512        RegisterInfo sp_reg;
9513        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9514        RegisterInfo dwarf_reg;
9515        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9516        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9517
9518        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9519            return false;
9520    }
9521    return true;
9522}
9523
9524
9525// A8.6.7 ADD (register-shifted register)
9526bool
9527EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9528{
9529#if 0
9530    if ConditionPassed() then
9531        EncodingSpecificOperations();
9532        shift_n = UInt(R[s]<7:0>);
9533        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9534        (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9535        R[d] = result;
9536        if setflags then
9537            APSR.N = result<31>;
9538            APSR.Z = IsZeroBit(result);
9539            APSR.C = carry;
9540            APSR.V = overflow;
9541#endif
9542
9543    bool success = false;
9544
9545    if (ConditionPassed(opcode))
9546    {
9547        uint32_t d;
9548        uint32_t n;
9549        uint32_t m;
9550        uint32_t s;
9551        bool setflags;
9552        ARM_ShifterType shift_t;
9553
9554        switch (encoding)
9555        {
9556            case eEncodingA1:
9557                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9558                d = Bits32 (opcode, 15, 12);
9559                n = Bits32 (opcode, 19, 16);
9560                m = Bits32 (opcode, 3, 0);
9561                s = Bits32 (opcode, 11, 8);
9562
9563                // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9564                setflags = BitIsSet (opcode, 20);
9565                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9566
9567                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9568                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9569                    return false;
9570                break;
9571
9572            default:
9573                return false;
9574        }
9575
9576        // shift_n = UInt(R[s]<7:0>);
9577        uint32_t Rs = ReadCoreReg (s, &success);
9578        if (!success)
9579            return false;
9580
9581        uint32_t shift_n = Bits32 (Rs, 7, 0);
9582
9583        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9584        uint32_t Rm = ReadCoreReg (m, &success);
9585        if (!success)
9586            return false;
9587
9588        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9589        if (!success)
9590            return false;
9591
9592        // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9593        uint32_t Rn = ReadCoreReg (n, &success);
9594        if (!success)
9595            return false;
9596
9597        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9598
9599        // R[d] = result;
9600        EmulateInstruction::Context context;
9601        context.type = eContextArithmetic;
9602        RegisterInfo reg_n;
9603        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9604        RegisterInfo reg_m;
9605        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9606
9607        context.SetRegisterRegisterOperands (reg_n, reg_m);
9608
9609        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9610            return false;
9611
9612        // if setflags then
9613            // APSR.N = result<31>;
9614            // APSR.Z = IsZeroBit(result);
9615            // APSR.C = carry;
9616            // APSR.V = overflow;
9617        if (setflags)
9618            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9619    }
9620    return true;
9621}
9622
9623// A8.6.213 SUB (register)
9624bool
9625EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9626{
9627#if 0
9628    if ConditionPassed() then
9629        EncodingSpecificOperations();
9630        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9631        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9632        if d == 15 then // Can only occur for ARM encoding
9633            ALUWritePC(result); // setflags is always FALSE here
9634        else
9635            R[d] = result;
9636            if setflags then
9637                APSR.N = result<31>;
9638                APSR.Z = IsZeroBit(result);
9639                APSR.C = carry;
9640                APSR.V = overflow;
9641#endif
9642
9643    bool success = false;
9644
9645    if (ConditionPassed(opcode))
9646    {
9647        uint32_t d;
9648        uint32_t n;
9649        uint32_t m;
9650        bool setflags;
9651        ARM_ShifterType shift_t;
9652        uint32_t shift_n;
9653
9654        switch (encoding)
9655        {
9656            case eEncodingT1:
9657                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9658                d = Bits32 (opcode, 2, 0);
9659                n = Bits32 (opcode, 5, 3);
9660                m = Bits32 (opcode, 8, 6);
9661                setflags = !InITBlock();
9662
9663                // (shift_t, shift_n) = (SRType_LSL, 0);
9664                shift_t = SRType_LSL;
9665                shift_n = 0;
9666
9667                break;
9668
9669            case eEncodingT2:
9670                // if Rd == �1111� && S == �1� then SEE CMP (register);
9671                // if Rn == �1101� then SEE SUB (SP minus register);
9672                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9673                d = Bits32 (opcode, 11, 8);
9674                n = Bits32 (opcode, 19, 16);
9675                m = Bits32 (opcode, 3, 0);
9676                setflags = BitIsSet (opcode, 20);
9677
9678                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9679                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9680
9681                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9682                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9683                    return false;
9684
9685                break;
9686
9687            case eEncodingA1:
9688                // if Rn == �1101� then SEE SUB (SP minus register);
9689                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9690                d = Bits32 (opcode, 15, 12);
9691                n = Bits32 (opcode, 19, 16);
9692                m = Bits32 (opcode, 3, 0);
9693                setflags = BitIsSet (opcode, 20);
9694
9695                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9696                if ((d == 15) && setflags)
9697                    EmulateSUBSPcLrEtc (opcode, encoding);
9698
9699                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9700                shift_n = DecodeImmShiftARM (opcode, shift_t);
9701
9702                break;
9703
9704            default:
9705                return false;
9706        }
9707
9708        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9709        uint32_t Rm = ReadCoreReg (m, &success);
9710        if (!success)
9711            return false;
9712
9713        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9714        if (!success)
9715            return false;
9716
9717        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9718        uint32_t Rn = ReadCoreReg (n, &success);
9719        if (!success)
9720            return false;
9721
9722        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9723
9724        // if d == 15 then // Can only occur for ARM encoding
9725            // ALUWritePC(result); // setflags is always FALSE here
9726        // else
9727            // R[d] = result;
9728            // if setflags then
9729                // APSR.N = result<31>;
9730                // APSR.Z = IsZeroBit(result);
9731                // APSR.C = carry;
9732                // APSR.V = overflow;
9733
9734        EmulateInstruction::Context context;
9735        context.type = eContextArithmetic;
9736        RegisterInfo reg_n;
9737        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9738        RegisterInfo reg_m;
9739        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9740        context.SetRegisterRegisterOperands (reg_n, reg_m);
9741
9742        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9743            return false;
9744    }
9745    return true;
9746}
9747
9748// A8.6.202 STREX
9749// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9750// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9751bool
9752EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9753{
9754#if 0
9755    if ConditionPassed() then
9756        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9757        address = R[n] + imm32;
9758        if ExclusiveMonitorsPass(address,4) then
9759            MemA[address,4] = R[t];
9760            R[d] = 0;
9761        else
9762            R[d] = 1;
9763#endif
9764
9765    bool success = false;
9766
9767    if (ConditionPassed(opcode))
9768    {
9769        uint32_t d;
9770        uint32_t t;
9771        uint32_t n;
9772        uint32_t imm32;
9773        const uint32_t addr_byte_size = GetAddressByteSize();
9774
9775        switch (encoding)
9776        {
9777            case eEncodingT1:
9778                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9779                d = Bits32 (opcode, 11, 8);
9780                t = Bits32 (opcode, 15, 12);
9781                n = Bits32 (opcode, 19, 16);
9782                imm32 = Bits32 (opcode, 7, 0) << 2;
9783
9784                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9785                if (BadReg (d) || BadReg (t) || (n == 15))
9786                  return false;
9787
9788                // if d == n || d == t then UNPREDICTABLE;
9789                if ((d == n) || (d == t))
9790                  return false;
9791
9792                break;
9793
9794            case eEncodingA1:
9795                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9796                d = Bits32 (opcode, 15, 12);
9797                t = Bits32 (opcode, 3, 0);
9798                n = Bits32 (opcode, 19, 16);
9799                imm32 = 0;
9800
9801                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9802                if ((d == 15) || (t == 15) || (n == 15))
9803                    return false;
9804
9805                // if d == n || d == t then UNPREDICTABLE;
9806                if ((d == n) || (d == t))
9807                    return false;
9808
9809                break;
9810
9811            default:
9812                return false;
9813        }
9814
9815        // address = R[n] + imm32;
9816        uint32_t Rn = ReadCoreReg (n, &success);
9817        if (!success)
9818            return false;
9819
9820        addr_t address = Rn + imm32;
9821
9822        RegisterInfo base_reg;
9823        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9824        RegisterInfo data_reg;
9825        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9826        EmulateInstruction::Context context;
9827        context.type = eContextRegisterStore;
9828        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9829
9830        // if ExclusiveMonitorsPass(address,4) then
9831        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9832        //                                                         always return true.
9833        if (true)
9834        {
9835            // MemA[address,4] = R[t];
9836            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9837            if (!success)
9838                return false;
9839
9840            if (!MemAWrite (context, address, Rt, addr_byte_size))
9841                return false;
9842
9843            // R[d] = 0;
9844            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9845                return false;
9846        }
9847        else
9848        {
9849            // R[d] = 1;
9850            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9851                return false;
9852        }
9853    }
9854    return true;
9855}
9856
9857// A8.6.197 STRB (immediate, ARM)
9858bool
9859EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9860{
9861#if 0
9862    if ConditionPassed() then
9863        EncodingSpecificOperations();
9864        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9865        address = if index then offset_addr else R[n];
9866        MemU[address,1] = R[t]<7:0>;
9867        if wback then R[n] = offset_addr;
9868#endif
9869
9870    bool success = false;
9871
9872    if (ConditionPassed(opcode))
9873    {
9874        uint32_t t;
9875        uint32_t n;
9876        uint32_t imm32;
9877        bool index;
9878        bool add;
9879        bool wback;
9880
9881        switch (encoding)
9882        {
9883            case eEncodingA1:
9884                // if P == �0� && W == �1� then SEE STRBT;
9885                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9886                t = Bits32 (opcode, 15, 12);
9887                n = Bits32 (opcode, 19, 16);
9888                imm32 = Bits32 (opcode, 11, 0);
9889
9890                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9891                index = BitIsSet (opcode, 24);
9892                add = BitIsSet (opcode, 23);
9893                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9894
9895                // if t == 15 then UNPREDICTABLE;
9896                if (t == 15)
9897                    return false;
9898
9899                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9900                if (wback && ((n == 15) || (n == t)))
9901                    return false;
9902
9903                break;
9904
9905            default:
9906                return false;
9907        }
9908
9909        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9910        uint32_t Rn = ReadCoreReg (n, &success);
9911        if (!success)
9912            return false;
9913
9914        addr_t offset_addr;
9915        if (add)
9916            offset_addr = Rn + imm32;
9917        else
9918            offset_addr = Rn - imm32;
9919
9920        // address = if index then offset_addr else R[n];
9921        addr_t address;
9922        if (index)
9923            address = offset_addr;
9924        else
9925            address = Rn;
9926
9927        // MemU[address,1] = R[t]<7:0>;
9928        uint32_t Rt = ReadCoreReg (t, &success);
9929        if (!success)
9930            return false;
9931
9932        RegisterInfo base_reg;
9933        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9934        RegisterInfo data_reg;
9935        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9936        EmulateInstruction::Context context;
9937        context.type = eContextRegisterStore;
9938        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9939
9940        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9941            return false;
9942
9943        // if wback then R[n] = offset_addr;
9944        if (wback)
9945        {
9946            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9947                return false;
9948        }
9949    }
9950    return true;
9951}
9952
9953// A8.6.194 STR (immediate, ARM)
9954bool
9955EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9956{
9957#if 0
9958    if ConditionPassed() then
9959        EncodingSpecificOperations();
9960        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9961        address = if index then offset_addr else R[n];
9962        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9963        if wback then R[n] = offset_addr;
9964#endif
9965
9966    bool success = false;
9967
9968    if (ConditionPassed(opcode))
9969    {
9970        uint32_t t;
9971        uint32_t n;
9972        uint32_t imm32;
9973        bool index;
9974        bool add;
9975        bool wback;
9976
9977        const uint32_t addr_byte_size = GetAddressByteSize();
9978
9979        switch (encoding)
9980        {
9981            case eEncodingA1:
9982                // if P == �0� && W == �1� then SEE STRT;
9983                // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9984                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9985                t = Bits32 (opcode, 15, 12);
9986                n = Bits32 (opcode, 19, 16);
9987                imm32 = Bits32 (opcode, 11, 0);
9988
9989                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9990                index = BitIsSet (opcode, 24);
9991                add = BitIsSet (opcode, 23);
9992                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9993
9994                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9995                if (wback && ((n == 15) || (n == t)))
9996                    return false;
9997
9998                break;
9999
10000            default:
10001                return false;
10002        }
10003
10004        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10005        uint32_t Rn = ReadCoreReg (n, &success);
10006        if (!success)
10007            return false;
10008
10009        addr_t offset_addr;
10010        if (add)
10011            offset_addr = Rn + imm32;
10012        else
10013            offset_addr = Rn - imm32;
10014
10015        // address = if index then offset_addr else R[n];
10016        addr_t address;
10017        if (index)
10018            address = offset_addr;
10019        else
10020            address = Rn;
10021
10022        RegisterInfo base_reg;
10023        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10024        RegisterInfo data_reg;
10025        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10026        EmulateInstruction::Context context;
10027        context.type = eContextRegisterStore;
10028        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10029
10030        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10031        uint32_t Rt = ReadCoreReg (t, &success);
10032        if (!success)
10033            return false;
10034
10035        if (t == 15)
10036        {
10037            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10038            if (!success)
10039                return false;
10040
10041            if (!MemUWrite (context, address, pc_value, addr_byte_size))
10042                return false;
10043        }
10044        else
10045        {
10046            if (!MemUWrite (context, address, Rt, addr_byte_size))
10047                  return false;
10048        }
10049
10050        // if wback then R[n] = offset_addr;
10051        if (wback)
10052        {
10053            context.type = eContextAdjustBaseRegister;
10054            context.SetImmediate (offset_addr);
10055
10056            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10057                return false;
10058        }
10059    }
10060    return true;
10061}
10062
10063// A8.6.66 LDRD (immediate)
10064// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10065// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10066bool
10067EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10068{
10069#if 0
10070    if ConditionPassed() then
10071        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10072        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10073        address = if index then offset_addr else R[n];
10074        R[t] = MemA[address,4];
10075        R[t2] = MemA[address+4,4];
10076        if wback then R[n] = offset_addr;
10077#endif
10078
10079    bool success = false;
10080
10081    if (ConditionPassed(opcode))
10082    {
10083        uint32_t t;
10084        uint32_t t2;
10085        uint32_t n;
10086        uint32_t imm32;
10087        bool index;
10088        bool add;
10089        bool wback;
10090
10091        switch (encoding)
10092        {
10093            case eEncodingT1:
10094                //if P == �0� && W == �0� then SEE �Related encodings�;
10095                //if Rn == �1111� then SEE LDRD (literal);
10096                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10097                t = Bits32 (opcode, 15, 12);
10098                t2 = Bits32 (opcode, 11, 8);
10099                n = Bits32 (opcode, 19, 16);
10100                imm32 = Bits32 (opcode, 7, 0) << 2;
10101
10102                //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10103                index = BitIsSet (opcode, 24);
10104                add = BitIsSet (opcode, 23);
10105                wback = BitIsSet (opcode, 21);
10106
10107                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10108                if (wback && ((n == t) || (n == t2)))
10109                    return false;
10110
10111                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10112                if (BadReg (t) || BadReg (t2) || (t == t2))
10113                    return false;
10114
10115                break;
10116
10117            case eEncodingA1:
10118                //if Rn == �1111� then SEE LDRD (literal);
10119                //if Rt<0> == �1� then UNPREDICTABLE;
10120                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10121                t = Bits32 (opcode, 15, 12);
10122                if (BitIsSet (t, 0))
10123                    return false;
10124                t2 = t + 1;
10125                n = Bits32 (opcode, 19, 16);
10126                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10127
10128                //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10129                index = BitIsSet (opcode, 24);
10130                add = BitIsSet (opcode, 23);
10131                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10132
10133                //if P == �0� && W == �1� then UNPREDICTABLE;
10134                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10135                    return false;
10136
10137                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10138                if (wback && ((n == t) || (n == t2)))
10139                    return false;
10140
10141                //if t2 == 15 then UNPREDICTABLE;
10142                if (t2 == 15)
10143                    return false;
10144
10145                break;
10146
10147            default:
10148                return false;
10149        }
10150
10151        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10152        uint32_t Rn = ReadCoreReg (n, &success);
10153        if (!success)
10154            return false;
10155
10156        addr_t offset_addr;
10157        if (add)
10158                  offset_addr = Rn + imm32;
10159        else
10160            offset_addr = Rn - imm32;
10161
10162        //address = if index then offset_addr else R[n];
10163        addr_t address;
10164        if (index)
10165            address = offset_addr;
10166        else
10167            address = Rn;
10168
10169        //R[t] = MemA[address,4];
10170        RegisterInfo base_reg;
10171        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10172
10173        EmulateInstruction::Context context;
10174        context.type = eContextRegisterLoad;
10175        context.SetRegisterPlusOffset (base_reg, address - Rn);
10176
10177        const uint32_t addr_byte_size = GetAddressByteSize();
10178        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10179        if (!success)
10180            return false;
10181
10182        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10183            return false;
10184
10185        //R[t2] = MemA[address+4,4];
10186
10187        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10188        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10189        if (!success)
10190            return false;
10191
10192        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10193            return false;
10194
10195        //if wback then R[n] = offset_addr;
10196        if (wback)
10197        {
10198            context.type = eContextAdjustBaseRegister;
10199            context.SetAddress (offset_addr);
10200
10201            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10202                return false;
10203        }
10204    }
10205    return true;
10206}
10207
10208// A8.6.68 LDRD (register)
10209// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10210// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10211bool
10212EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10213{
10214#if 0
10215    if ConditionPassed() then
10216        EncodingSpecificOperations();
10217        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10218        address = if index then offset_addr else R[n];
10219        R[t] = MemA[address,4];
10220        R[t2] = MemA[address+4,4];
10221        if wback then R[n] = offset_addr;
10222#endif
10223
10224    bool success = false;
10225
10226    if (ConditionPassed(opcode))
10227    {
10228        uint32_t t;
10229        uint32_t t2;
10230        uint32_t n;
10231        uint32_t m;
10232        bool index;
10233        bool add;
10234        bool wback;
10235
10236        switch (encoding)
10237        {
10238            case eEncodingA1:
10239                // if Rt<0> == �1� then UNPREDICTABLE;
10240                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10241                t = Bits32 (opcode, 15, 12);
10242                if (BitIsSet (t, 0))
10243                    return false;
10244                t2 = t + 1;
10245                n = Bits32 (opcode, 19, 16);
10246                m = Bits32 (opcode, 3, 0);
10247
10248                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10249                index = BitIsSet (opcode, 24);
10250                add = BitIsSet (opcode, 23);
10251                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10252
10253                // if P == �0� && W == �1� then UNPREDICTABLE;
10254                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10255                  return false;
10256
10257                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10258                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10259                  return false;
10260
10261                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10262                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10263                  return false;
10264
10265                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10266                if ((ArchVersion() < 6) && wback && (m == n))
10267                  return false;
10268                break;
10269
10270            default:
10271                return false;
10272        }
10273
10274        uint32_t Rn = ReadCoreReg (n, &success);
10275        if (!success)
10276            return false;
10277        RegisterInfo base_reg;
10278        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10279
10280        uint32_t Rm = ReadCoreReg (m, &success);
10281        if (!success)
10282            return false;
10283        RegisterInfo offset_reg;
10284        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10285
10286        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10287        addr_t offset_addr;
10288        if (add)
10289            offset_addr = Rn + Rm;
10290        else
10291            offset_addr = Rn - Rm;
10292
10293        // address = if index then offset_addr else R[n];
10294        addr_t address;
10295        if (index)
10296            address = offset_addr;
10297        else
10298            address = Rn;
10299
10300        EmulateInstruction::Context context;
10301        context.type = eContextRegisterLoad;
10302        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10303
10304        // R[t] = MemA[address,4];
10305        const uint32_t addr_byte_size = GetAddressByteSize();
10306        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10307        if (!success)
10308            return false;
10309
10310        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10311            return false;
10312
10313        // R[t2] = MemA[address+4,4];
10314
10315        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10316        if (!success)
10317            return false;
10318
10319        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10320            return false;
10321
10322        // if wback then R[n] = offset_addr;
10323        if (wback)
10324        {
10325            context.type = eContextAdjustBaseRegister;
10326            context.SetAddress (offset_addr);
10327
10328            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10329                return false;
10330        }
10331    }
10332    return true;
10333}
10334
10335// A8.6.200 STRD (immediate)
10336// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10337// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10338bool
10339EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10340{
10341#if 0
10342    if ConditionPassed() then
10343        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10344        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10345        address = if index then offset_addr else R[n];
10346        MemA[address,4] = R[t];
10347        MemA[address+4,4] = R[t2];
10348        if wback then R[n] = offset_addr;
10349#endif
10350
10351    bool success = false;
10352
10353    if (ConditionPassed(opcode))
10354    {
10355        uint32_t t;
10356        uint32_t t2;
10357        uint32_t n;
10358        uint32_t imm32;
10359        bool index;
10360        bool add;
10361        bool wback;
10362
10363        switch (encoding)
10364        {
10365            case eEncodingT1:
10366                // if P == �0� && W == �0� then SEE �Related encodings�;
10367                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10368                t = Bits32 (opcode, 15, 12);
10369                t2 = Bits32 (opcode, 11, 8);
10370                n = Bits32 (opcode, 19, 16);
10371                imm32 = Bits32 (opcode, 7, 0) << 2;
10372
10373                // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10374                index = BitIsSet (opcode, 24);
10375                add = BitIsSet (opcode, 23);
10376                wback = BitIsSet (opcode, 21);
10377
10378                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10379                if (wback && ((n == t) || (n == t2)))
10380                    return false;
10381
10382                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10383                if ((n == 15) || BadReg (t) || BadReg (t2))
10384                    return false;
10385
10386                break;
10387
10388            case eEncodingA1:
10389                // if Rt<0> == �1� then UNPREDICTABLE;
10390                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10391                t = Bits32 (opcode, 15, 12);
10392                if (BitIsSet (t, 0))
10393                    return false;
10394
10395                t2 = t + 1;
10396                n = Bits32 (opcode, 19, 16);
10397                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10398
10399                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10400                index = BitIsSet (opcode, 24);
10401                add = BitIsSet (opcode, 23);
10402                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10403
10404                // if P == �0� && W == �1� then UNPREDICTABLE;
10405                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10406                    return false;
10407
10408                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10409                if (wback && ((n == 15) || (n == t) || (n == t2)))
10410                    return false;
10411
10412                // if t2 == 15 then UNPREDICTABLE;
10413                if (t2 == 15)
10414                    return false;
10415
10416                break;
10417
10418            default:
10419                return false;
10420        }
10421
10422        RegisterInfo base_reg;
10423        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10424
10425        uint32_t Rn = ReadCoreReg (n, &success);
10426        if (!success)
10427            return false;
10428
10429        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10430        addr_t offset_addr;
10431        if (add)
10432            offset_addr = Rn + imm32;
10433        else
10434            offset_addr = Rn - imm32;
10435
10436        //address = if index then offset_addr else R[n];
10437        addr_t address;
10438        if (index)
10439            address = offset_addr;
10440        else
10441            address = Rn;
10442
10443        //MemA[address,4] = R[t];
10444        RegisterInfo data_reg;
10445        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10446
10447        uint32_t data = ReadCoreReg (t, &success);
10448        if (!success)
10449            return false;
10450
10451        EmulateInstruction::Context context;
10452        context.type = eContextRegisterStore;
10453        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10454
10455        const uint32_t addr_byte_size = GetAddressByteSize();
10456
10457        if (!MemAWrite (context, address, data, addr_byte_size))
10458            return false;
10459
10460        //MemA[address+4,4] = R[t2];
10461        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10462        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10463
10464        data = ReadCoreReg (t2, &success);
10465        if (!success)
10466            return false;
10467
10468        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10469            return false;
10470
10471        //if wback then R[n] = offset_addr;
10472        if (wback)
10473        {
10474            context.type = eContextAdjustBaseRegister;
10475            context.SetAddress (offset_addr);
10476
10477            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10478                return false;
10479        }
10480    }
10481    return true;
10482}
10483
10484
10485// A8.6.201 STRD (register)
10486bool
10487EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10488{
10489#if 0
10490    if ConditionPassed() then
10491        EncodingSpecificOperations();
10492        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10493        address = if index then offset_addr else R[n];
10494        MemA[address,4] = R[t];
10495        MemA[address+4,4] = R[t2];
10496        if wback then R[n] = offset_addr;
10497#endif
10498
10499    bool success = false;
10500
10501    if (ConditionPassed(opcode))
10502    {
10503        uint32_t t;
10504        uint32_t t2;
10505        uint32_t n;
10506        uint32_t m;
10507        bool index;
10508        bool add;
10509        bool wback;
10510
10511        switch (encoding)
10512        {
10513            case eEncodingA1:
10514                // if Rt<0> == �1� then UNPREDICTABLE;
10515                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10516                t = Bits32 (opcode, 15, 12);
10517                if (BitIsSet (t, 0))
10518                   return false;
10519
10520                t2 = t+1;
10521                n = Bits32 (opcode, 19, 16);
10522                m = Bits32 (opcode, 3, 0);
10523
10524                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10525                index = BitIsSet (opcode, 24);
10526                add = BitIsSet (opcode, 23);
10527                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10528
10529                // if P == �0� && W == �1� then UNPREDICTABLE;
10530                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10531                   return false;
10532
10533                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10534                if ((t2 == 15) || (m == 15))
10535                   return false;
10536
10537                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10538                if (wback && ((n == 15) || (n == t) || (n == t2)))
10539                   return false;
10540
10541                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10542                if ((ArchVersion() < 6) && wback && (m == n))
10543                   return false;
10544
10545                break;
10546
10547            default:
10548                return false;
10549        }
10550
10551        RegisterInfo base_reg;
10552        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10553        RegisterInfo offset_reg;
10554        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10555        RegisterInfo data_reg;
10556
10557        uint32_t Rn = ReadCoreReg (n, &success);
10558        if (!success)
10559            return false;
10560
10561        uint32_t Rm = ReadCoreReg (m, &success);
10562        if (!success)
10563            return false;
10564
10565        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10566        addr_t offset_addr;
10567        if (add)
10568            offset_addr = Rn + Rm;
10569        else
10570            offset_addr = Rn - Rm;
10571
10572        // address = if index then offset_addr else R[n];
10573        addr_t address;
10574        if (index)
10575            address = offset_addr;
10576        else
10577            address = Rn;
10578                          // MemA[address,4] = R[t];
10579        uint32_t Rt = ReadCoreReg (t, &success);
10580        if (!success)
10581            return false;
10582
10583        EmulateInstruction::Context context;
10584        context.type = eContextRegisterStore;
10585        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10586        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10587
10588        const uint32_t addr_byte_size = GetAddressByteSize();
10589
10590        if (!MemAWrite (context, address, Rt, addr_byte_size))
10591            return false;
10592
10593        // MemA[address+4,4] = R[t2];
10594        uint32_t Rt2 = ReadCoreReg (t2, &success);
10595        if (!success)
10596            return false;
10597
10598        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10599
10600        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10601
10602        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10603            return false;
10604
10605        // if wback then R[n] = offset_addr;
10606        if (wback)
10607        {
10608            context.type = eContextAdjustBaseRegister;
10609            context.SetAddress (offset_addr);
10610
10611            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10612                return false;
10613
10614        }
10615    }
10616    return true;
10617}
10618
10619// A8.6.319 VLDM
10620// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10621// an ARM core register.
10622bool
10623EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10624{
10625#if 0
10626    if ConditionPassed() then
10627        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10628        address = if add then R[n] else R[n]-imm32;
10629        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10630        for r = 0 to regs-1
10631            if single_regs then
10632                S[d+r] = MemA[address,4]; address = address+4;
10633            else
10634                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10635                // Combine the word-aligned words in the correct order for current endianness.
10636                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10637#endif
10638
10639    bool success = false;
10640
10641    if (ConditionPassed(opcode))
10642    {
10643        bool single_regs;
10644        bool add;
10645        bool wback;
10646        uint32_t d;
10647        uint32_t n;
10648        uint32_t imm32;
10649        uint32_t regs;
10650
10651        switch (encoding)
10652        {
10653            case eEncodingT1:
10654            case eEncodingA1:
10655                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10656                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10657                // if P == �1� && W == �0� then SEE VLDR;
10658                // if P == U && W == �1� then UNDEFINED;
10659                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10660                    return false;
10661
10662                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10663                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10664                single_regs = false;
10665                add = BitIsSet (opcode, 23);
10666                wback = BitIsSet (opcode, 21);
10667
10668                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10669                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10670                n = Bits32 (opcode, 19, 16);
10671                imm32 = Bits32 (opcode, 7, 0) << 2;
10672
10673                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10674                regs = Bits32 (opcode, 7, 0) / 2;
10675
10676                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10677                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10678                    return false;
10679
10680                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10681                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10682                    return false;
10683
10684                break;
10685
10686            case eEncodingT2:
10687            case eEncodingA2:
10688                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10689                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10690                // if P == �1� && W == �0� then SEE VLDR;
10691                // if P == U && W == �1� then UNDEFINED;
10692                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10693                    return false;
10694
10695                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10696                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10697                single_regs = true;
10698                add = BitIsSet (opcode, 23);
10699                wback = BitIsSet (opcode, 21);
10700                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10701                n = Bits32 (opcode, 19, 16);
10702
10703                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10704                imm32 = Bits32 (opcode, 7, 0) << 2;
10705                regs = Bits32 (opcode, 7, 0);
10706
10707                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10708                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10709                    return false;
10710
10711                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10712                if ((regs == 0) || ((d + regs) > 32))
10713                    return false;
10714                break;
10715
10716            default:
10717                return false;
10718        }
10719
10720        RegisterInfo base_reg;
10721        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10722
10723        uint32_t Rn = ReadCoreReg (n, &success);
10724        if (!success)
10725            return false;
10726
10727        // address = if add then R[n] else R[n]-imm32;
10728        addr_t address;
10729        if (add)
10730            address = Rn;
10731        else
10732            address = Rn - imm32;
10733
10734        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10735        EmulateInstruction::Context context;
10736
10737        if (wback)
10738        {
10739            uint32_t value;
10740            if (add)
10741                value = Rn + imm32;
10742            else
10743                value = Rn - imm32;
10744
10745            context.type = eContextAdjustBaseRegister;
10746            context.SetImmediateSigned (value - Rn);
10747            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10748                return false;
10749
10750        }
10751
10752        const uint32_t addr_byte_size = GetAddressByteSize();
10753        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10754
10755        context.type = eContextRegisterLoad;
10756
10757        // for r = 0 to regs-1
10758        for (uint32_t r = 0; r < regs; ++r)
10759        {
10760            if (single_regs)
10761            {
10762                // S[d+r] = MemA[address,4]; address = address+4;
10763                context.SetRegisterPlusOffset (base_reg, address - Rn);
10764
10765                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10766                if (!success)
10767                    return false;
10768
10769                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10770                    return false;
10771
10772                address = address + 4;
10773            }
10774            else
10775            {
10776                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10777                context.SetRegisterPlusOffset (base_reg, address - Rn);
10778                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10779                if (!success)
10780                    return false;
10781
10782                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10783                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10784                if (!success)
10785                    return false;
10786
10787                address = address + 8;
10788                // // Combine the word-aligned words in the correct order for current endianness.
10789                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10790                uint64_t data;
10791                if (GetByteOrder() == eByteOrderBig)
10792                {
10793                    data = word1;
10794                    data = (data << 32) | word2;
10795                }
10796                else
10797                {
10798                    data = word2;
10799                    data = (data << 32) | word1;
10800                }
10801
10802                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10803                    return false;
10804            }
10805        }
10806    }
10807    return true;
10808}
10809
10810// A8.6.399 VSTM
10811// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10812// ARM core register.
10813bool
10814EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10815{
10816#if 0
10817    if ConditionPassed() then
10818        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10819        address = if add then R[n] else R[n]-imm32;
10820        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10821        for r = 0 to regs-1
10822            if single_regs then
10823                MemA[address,4] = S[d+r]; address = address+4;
10824            else
10825                // Store as two word-aligned words in the correct order for current endianness.
10826                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10827                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10828                address = address+8;
10829#endif
10830
10831    bool success = false;
10832
10833    if (ConditionPassed (opcode))
10834    {
10835        bool single_regs;
10836        bool add;
10837        bool wback;
10838        uint32_t d;
10839        uint32_t n;
10840        uint32_t imm32;
10841        uint32_t regs;
10842
10843        switch (encoding)
10844        {
10845            case eEncodingT1:
10846            case eEncodingA1:
10847                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10848                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10849                // if P == �1� && W == �0� then SEE VSTR;
10850                // if P == U && W == �1� then UNDEFINED;
10851                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10852                    return false;
10853
10854                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10855                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10856                single_regs = false;
10857                add = BitIsSet (opcode, 23);
10858                wback = BitIsSet (opcode, 21);
10859
10860                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10861                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10862                n = Bits32 (opcode, 19, 16);
10863                imm32 = Bits32 (opcode, 7, 0) << 2;
10864
10865                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10866                regs = Bits32 (opcode, 7, 0) / 2;
10867
10868                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10869                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10870                    return false;
10871
10872                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10873                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10874                    return false;
10875
10876                break;
10877
10878            case eEncodingT2:
10879            case eEncodingA2:
10880                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10881                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10882                // if P == �1� && W == �0� then SEE VSTR;
10883                // if P == U && W == �1� then UNDEFINED;
10884                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10885                    return false;
10886
10887                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10888                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10889                single_regs = true;
10890                add = BitIsSet (opcode, 23);
10891                wback = BitIsSet (opcode, 21);
10892                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10893                n = Bits32 (opcode, 19, 16);
10894
10895                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10896                imm32 = Bits32 (opcode, 7, 0) << 2;
10897                regs = Bits32 (opcode, 7, 0);
10898
10899                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10900                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10901                    return false;
10902
10903                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10904                if ((regs == 0) || ((d + regs) > 32))
10905                    return false;
10906
10907                break;
10908
10909            default:
10910                return false;
10911        }
10912
10913        RegisterInfo base_reg;
10914        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10915
10916        uint32_t Rn = ReadCoreReg (n, &success);
10917        if (!success)
10918            return false;
10919
10920        // address = if add then R[n] else R[n]-imm32;
10921        addr_t address;
10922        if (add)
10923            address = Rn;
10924        else
10925            address = Rn - imm32;
10926
10927        EmulateInstruction::Context context;
10928        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10929        if (wback)
10930        {
10931            uint32_t value;
10932            if (add)
10933                value = Rn + imm32;
10934            else
10935                value = Rn - imm32;
10936
10937            context.type = eContextAdjustBaseRegister;
10938            context.SetRegisterPlusOffset (base_reg, value - Rn);
10939
10940            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10941                return false;
10942        }
10943
10944        const uint32_t addr_byte_size = GetAddressByteSize();
10945        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10946
10947        context.type = eContextRegisterStore;
10948        // for r = 0 to regs-1
10949        for (uint32_t r = 0; r < regs; ++r)
10950        {
10951
10952            if (single_regs)
10953            {
10954                // MemA[address,4] = S[d+r]; address = address+4;
10955                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10956                if (!success)
10957                    return false;
10958
10959                RegisterInfo data_reg;
10960                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10961                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10962                if (!MemAWrite (context, address, data, addr_byte_size))
10963                    return false;
10964
10965                address = address + 4;
10966            }
10967            else
10968            {
10969                // // Store as two word-aligned words in the correct order for current endianness.
10970                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10971                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10972                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10973                if (!success)
10974                    return false;
10975
10976                RegisterInfo data_reg;
10977                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10978
10979                if (GetByteOrder() == eByteOrderBig)
10980                {
10981                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10982                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10983                        return false;
10984
10985                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10986                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10987                        return false;
10988                }
10989                else
10990                {
10991                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10992                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10993                        return false;
10994
10995                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10996                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10997                        return false;
10998                }
10999                // address = address+8;
11000                address = address + 8;
11001            }
11002        }
11003    }
11004    return true;
11005}
11006
11007// A8.6.320
11008// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11009// an optional offset.
11010bool
11011EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11012{
11013#if 0
11014    if ConditionPassed() then
11015        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11016        base = if n == 15 then Align(PC,4) else R[n];
11017        address = if add then (base + imm32) else (base - imm32);
11018        if single_reg then
11019            S[d] = MemA[address,4];
11020        else
11021            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11022            // Combine the word-aligned words in the correct order for current endianness.
11023            D[d] = if BigEndian() then word1:word2 else word2:word1;
11024#endif
11025
11026    bool success = false;
11027
11028    if (ConditionPassed (opcode))
11029    {
11030        bool single_reg;
11031        bool add;
11032        uint32_t imm32;
11033        uint32_t d;
11034        uint32_t n;
11035
11036        switch (encoding)
11037        {
11038            case eEncodingT1:
11039            case eEncodingA1:
11040                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11041                single_reg = false;
11042                add = BitIsSet (opcode, 23);
11043                imm32 = Bits32 (opcode, 7, 0) << 2;
11044
11045                // d = UInt(D:Vd); n = UInt(Rn);
11046                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11047                n = Bits32 (opcode, 19, 16);
11048
11049                break;
11050
11051            case eEncodingT2:
11052            case eEncodingA2:
11053                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11054                single_reg = true;
11055                add = BitIsSet (opcode, 23);
11056                imm32 = Bits32 (opcode, 7, 0) << 2;
11057
11058                // d = UInt(Vd:D); n = UInt(Rn);
11059                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11060                n = Bits32 (opcode, 19, 16);
11061
11062                break;
11063
11064            default:
11065                return false;
11066        }
11067        RegisterInfo base_reg;
11068        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11069
11070        uint32_t Rn = ReadCoreReg (n, &success);
11071        if (!success)
11072            return false;
11073
11074        // base = if n == 15 then Align(PC,4) else R[n];
11075        uint32_t base;
11076        if (n == 15)
11077            base = AlignPC (Rn);
11078        else
11079            base = Rn;
11080
11081        // address = if add then (base + imm32) else (base - imm32);
11082        addr_t address;
11083        if (add)
11084            address = base + imm32;
11085        else
11086            address = base - imm32;
11087
11088        const uint32_t addr_byte_size = GetAddressByteSize();
11089        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11090
11091        EmulateInstruction::Context context;
11092        context.type = eContextRegisterLoad;
11093        context.SetRegisterPlusOffset (base_reg, address - base);
11094
11095        if (single_reg)
11096        {
11097            // S[d] = MemA[address,4];
11098            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11099            if (!success)
11100                return false;
11101
11102            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11103                return false;
11104        }
11105        else
11106        {
11107            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11108            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11109            if (!success)
11110                return false;
11111
11112            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11113            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11114            if (!success)
11115                return false;
11116            // // Combine the word-aligned words in the correct order for current endianness.
11117            // D[d] = if BigEndian() then word1:word2 else word2:word1;
11118            uint64_t data64;
11119            if (GetByteOrder() == eByteOrderBig)
11120            {
11121                data64 = word1;
11122                data64 = (data64 << 32) | word2;
11123            }
11124            else
11125            {
11126                data64 = word2;
11127                data64 = (data64 << 32) | word1;
11128            }
11129
11130            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11131                return false;
11132        }
11133    }
11134    return true;
11135}
11136
11137// A8.6.400 VSTR
11138// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11139// optional offset.
11140bool
11141EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11142{
11143#if 0
11144    if ConditionPassed() then
11145        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11146        address = if add then (R[n] + imm32) else (R[n] - imm32);
11147        if single_reg then
11148            MemA[address,4] = S[d];
11149        else
11150            // Store as two word-aligned words in the correct order for current endianness.
11151            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11152            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11153#endif
11154
11155    bool success = false;
11156
11157    if (ConditionPassed (opcode))
11158    {
11159        bool single_reg;
11160        bool add;
11161        uint32_t imm32;
11162        uint32_t d;
11163        uint32_t n;
11164
11165        switch (encoding)
11166        {
11167            case eEncodingT1:
11168            case eEncodingA1:
11169                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11170                single_reg = false;
11171                add = BitIsSet (opcode, 23);
11172                imm32 = Bits32 (opcode, 7, 0) << 2;
11173
11174                // d = UInt(D:Vd); n = UInt(Rn);
11175                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11176                n = Bits32 (opcode, 19, 16);
11177
11178                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11179                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11180                    return false;
11181
11182                break;
11183
11184            case eEncodingT2:
11185            case eEncodingA2:
11186                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11187                single_reg = true;
11188                add = BitIsSet (opcode, 23);
11189                imm32 = Bits32 (opcode, 7, 0) << 2;
11190
11191                // d = UInt(Vd:D); n = UInt(Rn);
11192                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11193                n = Bits32 (opcode, 19, 16);
11194
11195                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11196                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11197                    return false;
11198
11199                break;
11200
11201            default:
11202                return false;
11203        }
11204
11205        RegisterInfo base_reg;
11206        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11207
11208        uint32_t Rn = ReadCoreReg (n, &success);
11209        if (!success)
11210            return false;
11211
11212        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11213        addr_t address;
11214        if (add)
11215            address = Rn + imm32;
11216        else
11217            address = Rn - imm32;
11218
11219        const uint32_t addr_byte_size = GetAddressByteSize();
11220        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11221
11222        RegisterInfo data_reg;
11223        GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11224        EmulateInstruction::Context context;
11225        context.type = eContextRegisterStore;
11226        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11227
11228        if (single_reg)
11229        {
11230            // MemA[address,4] = S[d];
11231            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11232            if (!success)
11233                return false;
11234
11235            if (!MemAWrite (context, address, data, addr_byte_size))
11236                return false;
11237        }
11238        else
11239        {
11240            // // Store as two word-aligned words in the correct order for current endianness.
11241            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11242            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11243            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11244            if (!success)
11245                return false;
11246
11247            if (GetByteOrder() == eByteOrderBig)
11248            {
11249                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11250                    return false;
11251
11252                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11253                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11254                    return false;
11255            }
11256            else
11257            {
11258                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11259                    return false;
11260
11261                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11262                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11263                    return false;
11264            }
11265        }
11266    }
11267    return true;
11268}
11269
11270// A8.6.307 VLDI1 (multiple single elements)
11271// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11272// element of each register is loaded.
11273bool
11274EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11275{
11276#if 0
11277    if ConditionPassed() then
11278        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11279        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11280        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11281        for r = 0 to regs-1
11282            for e = 0 to elements-1
11283                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11284                address = address + ebytes;
11285#endif
11286
11287    bool success = false;
11288
11289    if (ConditionPassed (opcode))
11290    {
11291        uint32_t regs;
11292        uint32_t alignment;
11293        uint32_t ebytes;
11294        uint32_t esize;
11295        uint32_t elements;
11296        uint32_t d;
11297        uint32_t n;
11298        uint32_t m;
11299        bool wback;
11300        bool register_index;
11301
11302        switch (encoding)
11303        {
11304            case eEncodingT1:
11305            case eEncodingA1:
11306            {
11307                // case type of
11308                    // when �0111�
11309                        // regs = 1; if align<1> == �1� then UNDEFINED;
11310                    // when �1010�
11311                        // regs = 2; if align == �11� then UNDEFINED;
11312                    // when �0110�
11313                        // regs = 3; if align<1> == �1� then UNDEFINED;
11314                    // when �0010�
11315                        // regs = 4;
11316                    // otherwise
11317                        // SEE �Related encodings�;
11318                uint32_t type = Bits32 (opcode, 11, 8);
11319                uint32_t align = Bits32 (opcode, 5, 4);
11320                if (type == 7) // '0111'
11321                {
11322                    regs = 1;
11323                    if (BitIsSet (align, 1))
11324                        return false;
11325                }
11326                else if (type == 10) // '1010'
11327                {
11328                    regs = 2;
11329                    if (align == 3)
11330                        return false;
11331
11332                }
11333                else if (type == 6) // '0110'
11334                {
11335                    regs = 3;
11336                    if (BitIsSet (align, 1))
11337                        return false;
11338                }
11339                else if (type == 2) // '0010'
11340                {
11341                    regs = 4;
11342                }
11343                else
11344                    return false;
11345
11346                // alignment = if align == �00� then 1 else 4 << UInt(align);
11347                if (align == 0)
11348                    alignment = 1;
11349                else
11350                    alignment = 4 << align;
11351
11352                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11353                ebytes = 1 << Bits32 (opcode, 7, 6);
11354                esize = 8 * ebytes;
11355                elements = 8 / ebytes;
11356
11357                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11358                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11359                n = Bits32 (opcode, 19, 15);
11360                m = Bits32 (opcode, 3, 0);
11361
11362                // wback = (m != 15); register_index = (m != 15 && m != 13);
11363                wback = (m != 15);
11364                register_index = ((m != 15) && (m != 13));
11365
11366                // if d+regs > 32 then UNPREDICTABLE;
11367                if ((d + regs) > 32)
11368                    return false;
11369            }
11370                break;
11371
11372            default:
11373                return false;
11374        }
11375
11376        RegisterInfo base_reg;
11377        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11378
11379        uint32_t Rn = ReadCoreReg (n, &success);
11380        if (!success)
11381            return false;
11382
11383        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11384        addr_t address = Rn;
11385        if ((address % alignment) != 0)
11386            return false;
11387
11388        EmulateInstruction::Context context;
11389        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11390        if (wback)
11391        {
11392            uint32_t Rm = ReadCoreReg (m, &success);
11393            if (!success)
11394                return false;
11395
11396            uint32_t offset;
11397            if (register_index)
11398                offset = Rm;
11399            else
11400                offset = 8 * regs;
11401
11402            uint32_t value = Rn + offset;
11403            context.type = eContextAdjustBaseRegister;
11404            context.SetRegisterPlusOffset (base_reg, offset);
11405
11406            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11407                return false;
11408
11409        }
11410
11411        // for r = 0 to regs-1
11412        for (uint32_t r = 0; r < regs; ++r)
11413        {
11414            // for e = 0 to elements-1
11415            uint64_t assembled_data = 0;
11416            for (uint32_t e = 0; e < elements; ++e)
11417            {
11418                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11419                context.type = eContextRegisterLoad;
11420                context.SetRegisterPlusOffset (base_reg, address - Rn);
11421                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11422                if (!success)
11423                    return false;
11424
11425                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11426
11427                // address = address + ebytes;
11428                address = address + ebytes;
11429            }
11430            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11431                return false;
11432        }
11433    }
11434    return true;
11435}
11436
11437// A8.6.308 VLD1 (single element to one lane)
11438//
11439bool
11440EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11441{
11442#if 0
11443    if ConditionPassed() then
11444        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11445        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11446        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11447        Elem[D[d],index,esize] = MemU[address,ebytes];
11448#endif
11449
11450    bool success = false;
11451
11452    if (ConditionPassed (opcode))
11453    {
11454        uint32_t ebytes;
11455        uint32_t esize;
11456        uint32_t index;
11457        uint32_t alignment;
11458        uint32_t d;
11459        uint32_t n;
11460        uint32_t m;
11461        bool wback;
11462        bool register_index;
11463
11464        switch (encoding)
11465        {
11466            case eEncodingT1:
11467            case eEncodingA1:
11468            {
11469                uint32_t size = Bits32 (opcode, 11, 10);
11470                uint32_t index_align = Bits32 (opcode, 7, 4);
11471                // if size == �11� then SEE VLD1 (single element to all lanes);
11472                if (size == 3)
11473                   return EmulateVLD1SingleAll (opcode, encoding);
11474                // case size of
11475                if (size == 0) // when '00'
11476                {
11477                    // if index_align<0> != �0� then UNDEFINED;
11478                    if (BitIsClear (index_align, 0))
11479                        return false;
11480
11481                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11482                    ebytes = 1;
11483                    esize = 8;
11484                    index = Bits32 (index_align, 3, 1);
11485                    alignment = 1;
11486                }
11487                else if (size == 1) // when �01�
11488                {
11489                    // if index_align<1> != �0� then UNDEFINED;
11490                    if (BitIsClear (index_align, 1))
11491                        return false;
11492
11493                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11494                    ebytes = 2;
11495                    esize = 16;
11496                    index = Bits32 (index_align, 3, 2);
11497
11498                    // alignment = if index_align<0> == �0� then 1 else 2;
11499                    if (BitIsClear (index_align, 0))
11500                        alignment = 1;
11501                    else
11502                        alignment = 2;
11503                }
11504                else if (size == 2) // when �10�
11505                {
11506                    // if index_align<2> != �0� then UNDEFINED;
11507                    if (BitIsClear (index_align, 2))
11508                        return false;
11509
11510                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11511                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11512                        return false;
11513
11514                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11515                    ebytes = 4;
11516                    esize = 32;
11517                    index = Bit32 (index_align, 3);
11518
11519                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11520                    if (Bits32 (index_align, 1, 0) == 0)
11521                        alignment = 1;
11522                    else
11523                        alignment = 4;
11524                }
11525                else
11526                {
11527                    return false;
11528                }
11529                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11530                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11531                n = Bits32 (opcode, 19, 16);
11532                m = Bits32 (opcode, 3, 0);
11533
11534                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11535                wback = (m != 15);
11536                register_index = ((m != 15) && (m != 13));
11537
11538                if (n == 15)
11539                    return false;
11540
11541            }
11542                break;
11543
11544            default:
11545                return false;
11546        }
11547
11548        RegisterInfo base_reg;
11549        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11550
11551        uint32_t Rn = ReadCoreReg (n, &success);
11552        if (!success)
11553            return false;
11554
11555        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11556        addr_t address = Rn;
11557        if ((address % alignment) != 0)
11558            return false;
11559
11560        EmulateInstruction::Context context;
11561        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11562        if (wback)
11563        {
11564            uint32_t Rm = ReadCoreReg (m, &success);
11565            if (!success)
11566                return false;
11567
11568            uint32_t offset;
11569            if (register_index)
11570                offset = Rm;
11571            else
11572                offset = ebytes;
11573
11574            uint32_t value = Rn + offset;
11575
11576            context.type = eContextAdjustBaseRegister;
11577            context.SetRegisterPlusOffset (base_reg, offset);
11578
11579            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11580                return false;
11581        }
11582
11583        // Elem[D[d],index,esize] = MemU[address,ebytes];
11584        uint32_t element = MemURead (context, address, esize, 0, &success);
11585        if (!success)
11586            return false;
11587
11588        element = element << (index * esize);
11589
11590        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11591        if (!success)
11592            return false;
11593
11594        uint64_t all_ones = -1;
11595        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11596                                                          // at element & to the right of element.
11597        if (index > 0)
11598            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11599                                                                     // now mask should be 0's where element goes & 1's
11600                                                                     // everywhere else.
11601
11602        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11603        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11604
11605        context.type = eContextRegisterLoad;
11606        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11607            return false;
11608    }
11609    return true;
11610}
11611
11612// A8.6.391 VST1 (multiple single elements)
11613// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11614// interleaving.  Every element of each register is stored.
11615bool
11616EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11617{
11618#if 0
11619    if ConditionPassed() then
11620        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11621        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11622        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11623        for r = 0 to regs-1
11624            for e = 0 to elements-1
11625                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11626                address = address + ebytes;
11627#endif
11628
11629    bool success = false;
11630
11631    if (ConditionPassed (opcode))
11632    {
11633        uint32_t regs;
11634        uint32_t alignment;
11635        uint32_t ebytes;
11636        uint32_t esize;
11637        uint32_t elements;
11638        uint32_t d;
11639        uint32_t n;
11640        uint32_t m;
11641        bool wback;
11642        bool register_index;
11643
11644        switch (encoding)
11645        {
11646            case eEncodingT1:
11647            case eEncodingA1:
11648            {
11649                uint32_t type = Bits32 (opcode, 11, 8);
11650                uint32_t align = Bits32 (opcode, 5, 4);
11651
11652                // case type of
11653                if (type == 7)    // when �0111�
11654                {
11655                    // regs = 1; if align<1> == �1� then UNDEFINED;
11656                    regs = 1;
11657                    if (BitIsSet (align, 1))
11658                        return false;
11659                }
11660                else if (type == 10) // when �1010�
11661                {
11662                    // regs = 2; if align == �11� then UNDEFINED;
11663                    regs = 2;
11664                    if (align == 3)
11665                        return false;
11666                }
11667                else if (type == 6) // when �0110�
11668                {
11669                    // regs = 3; if align<1> == �1� then UNDEFINED;
11670                    regs = 3;
11671                    if (BitIsSet (align, 1))
11672                        return false;
11673                }
11674                else if (type == 2) // when �0010�
11675                    // regs = 4;
11676                    regs = 4;
11677                else // otherwise
11678                    // SEE �Related encodings�;
11679                    return false;
11680
11681                // alignment = if align == �00� then 1 else 4 << UInt(align);
11682                if (align == 0)
11683                    alignment = 1;
11684                else
11685                    alignment = 4 << align;
11686
11687                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11688                ebytes = 1 << Bits32 (opcode,7, 6);
11689                esize = 8 * ebytes;
11690                elements = 8 / ebytes;
11691
11692                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11693                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11694                n = Bits32 (opcode, 19, 16);
11695                m = Bits32 (opcode, 3, 0);
11696
11697                // wback = (m != 15); register_index = (m != 15 && m != 13);
11698                wback = (m != 15);
11699                register_index = ((m != 15) && (m != 13));
11700
11701                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11702                if ((d + regs) > 32)
11703                    return false;
11704
11705                if (n == 15)
11706                    return false;
11707
11708            }
11709                break;
11710
11711            default:
11712                return false;
11713        }
11714
11715        RegisterInfo base_reg;
11716        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11717
11718        uint32_t Rn = ReadCoreReg (n, &success);
11719        if (!success)
11720            return false;
11721
11722        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11723        addr_t address = Rn;
11724        if ((address % alignment) != 0)
11725            return false;
11726
11727        EmulateInstruction::Context context;
11728        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11729        if (wback)
11730        {
11731            uint32_t Rm = ReadCoreReg (m, &success);
11732            if (!success)
11733                return false;
11734
11735            uint32_t offset;
11736            if (register_index)
11737                offset = Rm;
11738            else
11739                offset = 8 * regs;
11740
11741            context.type = eContextAdjustBaseRegister;
11742            context.SetRegisterPlusOffset (base_reg, offset);
11743
11744            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11745                return false;
11746        }
11747
11748        RegisterInfo data_reg;
11749        context.type = eContextRegisterStore;
11750        // for r = 0 to regs-1
11751        for (uint32_t r = 0; r < regs; ++r)
11752        {
11753            GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11754            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11755            if (!success)
11756                return false;
11757
11758             // for e = 0 to elements-1
11759            for (uint32_t e = 0; e < elements; ++e)
11760            {
11761                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11762                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11763
11764                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11765                if (!MemUWrite (context, address, word, ebytes))
11766                    return false;
11767
11768                // address = address + ebytes;
11769                address = address + ebytes;
11770            }
11771        }
11772    }
11773    return true;
11774}
11775
11776// A8.6.392 VST1 (single element from one lane)
11777// This instruction stores one element to memory from one element of a register.
11778bool
11779EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11780{
11781#if 0
11782    if ConditionPassed() then
11783        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11784        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11785        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11786        MemU[address,ebytes] = Elem[D[d],index,esize];
11787#endif
11788
11789    bool success = false;
11790
11791    if (ConditionPassed (opcode))
11792    {
11793        uint32_t ebytes;
11794        uint32_t esize;
11795        uint32_t index;
11796        uint32_t alignment;
11797        uint32_t d;
11798        uint32_t n;
11799        uint32_t m;
11800        bool wback;
11801        bool register_index;
11802
11803        switch (encoding)
11804        {
11805            case eEncodingT1:
11806            case eEncodingA1:
11807            {
11808                uint32_t size = Bits32 (opcode, 11, 10);
11809                uint32_t index_align = Bits32 (opcode, 7, 4);
11810
11811                // if size == �11� then UNDEFINED;
11812                if (size == 3)
11813                    return false;
11814
11815                // case size of
11816                if (size == 0) // when �00�
11817                {
11818                    // if index_align<0> != �0� then UNDEFINED;
11819                    if (BitIsClear (index_align, 0))
11820                        return false;
11821                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11822                    ebytes = 1;
11823                    esize = 8;
11824                    index = Bits32 (index_align, 3, 1);
11825                    alignment = 1;
11826                }
11827                else if (size == 1) // when �01�
11828                {
11829                    // if index_align<1> != �0� then UNDEFINED;
11830                    if (BitIsClear (index_align, 1))
11831                        return false;
11832
11833                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11834                    ebytes = 2;
11835                    esize = 16;
11836                    index = Bits32 (index_align, 3, 2);
11837
11838                    // alignment = if index_align<0> == �0� then 1 else 2;
11839                    if (BitIsClear (index_align, 0))
11840                        alignment = 1;
11841                    else
11842                        alignment = 2;
11843                }
11844                else if (size == 2) // when �10�
11845                {
11846                    // if index_align<2> != �0� then UNDEFINED;
11847                    if (BitIsClear (index_align, 2))
11848                        return false;
11849
11850                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11851                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11852                        return false;
11853
11854                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11855                    ebytes = 4;
11856                    esize = 32;
11857                    index = Bit32 (index_align, 3);
11858
11859                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11860                    if (Bits32 (index_align, 1, 0) == 0)
11861                        alignment = 1;
11862                    else
11863                        alignment = 4;
11864                }
11865                else
11866                {
11867                    return false;
11868                }
11869                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11870                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11871                n = Bits32 (opcode, 19, 16);
11872                m = Bits32 (opcode, 3, 0);
11873
11874                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11875                wback = (m != 15);
11876                register_index = ((m != 15) && (m != 13));
11877
11878                if (n == 15)
11879                    return false;
11880            }
11881                break;
11882
11883            default:
11884                return false;
11885        }
11886
11887        RegisterInfo base_reg;
11888        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11889
11890        uint32_t Rn = ReadCoreReg (n, &success);
11891        if (!success)
11892            return false;
11893
11894        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11895        addr_t address = Rn;
11896        if ((address % alignment) != 0)
11897            return false;
11898
11899        EmulateInstruction::Context context;
11900        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11901        if (wback)
11902        {
11903            uint32_t Rm = ReadCoreReg (m, &success);
11904            if (!success)
11905                return false;
11906
11907            uint32_t offset;
11908            if (register_index)
11909                offset = Rm;
11910            else
11911                offset = ebytes;
11912
11913            context.type = eContextAdjustBaseRegister;
11914            context.SetRegisterPlusOffset (base_reg, offset);
11915
11916            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11917                return false;
11918        }
11919
11920        // MemU[address,ebytes] = Elem[D[d],index,esize];
11921        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11922        if (!success)
11923            return false;
11924
11925        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11926
11927        RegisterInfo data_reg;
11928        GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11929        context.type = eContextRegisterStore;
11930        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11931
11932        if (!MemUWrite (context, address, word, ebytes))
11933            return false;
11934    }
11935    return true;
11936}
11937
11938// A8.6.309 VLD1 (single element to all lanes)
11939// This instruction loads one element from memory into every element of one or two vectors.
11940bool
11941EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11942{
11943#if 0
11944    if ConditionPassed() then
11945        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11946        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11947        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11948        replicated_element = Replicate(MemU[address,ebytes], elements);
11949        for r = 0 to regs-1
11950            D[d+r] = replicated_element;
11951#endif
11952
11953    bool success = false;
11954
11955    if (ConditionPassed (opcode))
11956    {
11957        uint32_t ebytes;
11958        uint32_t elements;
11959        uint32_t regs;
11960        uint32_t alignment;
11961        uint32_t d;
11962        uint32_t n;
11963        uint32_t m;
11964        bool wback;
11965        bool register_index;
11966
11967        switch (encoding)
11968        {
11969            case eEncodingT1:
11970            case eEncodingA1:
11971            {
11972                //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11973                uint32_t size = Bits32 (opcode, 7, 6);
11974                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11975                    return false;
11976
11977                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11978                ebytes = 1 << size;
11979                elements = 8 / ebytes;
11980                if (BitIsClear (opcode, 5))
11981                    regs = 1;
11982                else
11983                    regs = 2;
11984
11985                //alignment = if a == �0� then 1 else ebytes;
11986                if (BitIsClear (opcode, 4))
11987                    alignment = 1;
11988                else
11989                    alignment = ebytes;
11990
11991                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11992                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11993                n = Bits32 (opcode, 19, 16);
11994                m = Bits32 (opcode, 3, 0);
11995
11996                //wback = (m != 15); register_index = (m != 15 && m != 13);
11997                wback = (m != 15);
11998                register_index = ((m != 15) && (m != 13));
11999
12000                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12001                if ((d + regs) > 32)
12002                    return false;
12003
12004                if (n == 15)
12005                    return false;
12006            }
12007            break;
12008
12009            default:
12010                return false;
12011        }
12012
12013        RegisterInfo base_reg;
12014        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12015
12016        uint32_t Rn = ReadCoreReg (n, &success);
12017        if (!success)
12018            return false;
12019
12020        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12021        addr_t address = Rn;
12022        if ((address % alignment) != 0)
12023            return false;
12024
12025        EmulateInstruction::Context context;
12026        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12027        if (wback)
12028        {
12029            uint32_t Rm = ReadCoreReg (m, &success);
12030            if (!success)
12031                return false;
12032
12033            uint32_t offset;
12034            if (register_index)
12035                offset = Rm;
12036            else
12037                offset = ebytes;
12038
12039            context.type = eContextAdjustBaseRegister;
12040            context.SetRegisterPlusOffset (base_reg, offset);
12041
12042            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12043                return false;
12044        }
12045
12046        // replicated_element = Replicate(MemU[address,ebytes], elements);
12047
12048        context.type = eContextRegisterLoad;
12049        uint64_t word = MemURead (context, address, ebytes, 0, &success);
12050        if (!success)
12051            return false;
12052
12053        uint64_t replicated_element = 0;
12054        uint32_t esize = ebytes * 8;
12055        for (uint32_t e = 0; e < elements; ++e)
12056            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12057
12058        // for r = 0 to regs-1
12059        for (uint32_t r = 0; r < regs; ++r)
12060        {
12061            // D[d+r] = replicated_element;
12062            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12063                return false;
12064        }
12065    }
12066    return true;
12067}
12068
12069// B6.2.13 SUBS PC, LR and related instructions
12070//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12071// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12072bool
12073EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12074{
12075#if 0
12076    if ConditionPassed() then
12077        EncodingSpecificOperations();
12078        if CurrentInstrSet() == InstrSet_ThumbEE then
12079            UNPREDICTABLE;
12080        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12081        case opcode of
12082            when �0000� result = R[n] AND operand2; // AND
12083            when �0001result = R[n] EOR operand2; // EOR
12084            when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12085            when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12086            when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12087            when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12088            when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12089            when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12090            when1100result = R[n] OR operand2; // ORR
12091            when1101result = operand2; // MOV
12092            when1110result = R[n] AND NOT(operand2); // BIC
12093            when1111result = NOT(operand2); // MVN
12094        CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12095        BranchWritePC(result);
12096#endif
12097
12098    bool success = false;
12099
12100    if (ConditionPassed (opcode))
12101    {
12102        uint32_t n;
12103        uint32_t m;
12104        uint32_t imm32;
12105        bool register_form;
12106        ARM_ShifterType shift_t;
12107        uint32_t shift_n;
12108        uint32_t code;
12109
12110        switch (encoding)
12111        {
12112            case eEncodingT1:
12113                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12114                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12115                n = 14;
12116                imm32 = Bits32 (opcode, 7, 0);
12117                register_form = false;
12118                code = 2;
12119
12120                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12121                if (InITBlock() && !LastInITBlock())
12122                    return false;
12123
12124                break;
12125
12126            case eEncodingA1:
12127                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12128                n = Bits32 (opcode, 19, 16);
12129                imm32 = ARMExpandImm (opcode);
12130                register_form = false;
12131                code = Bits32 (opcode, 24, 21);
12132
12133                break;
12134
12135            case eEncodingA2:
12136                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12137                n = Bits32 (opcode, 19, 16);
12138                m = Bits32 (opcode, 3, 0);
12139                register_form = true;
12140
12141                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12142                shift_n = DecodeImmShiftARM (opcode, shift_t);
12143
12144                break;
12145
12146            default:
12147                return false;
12148        }
12149
12150        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12151        uint32_t operand2;
12152        if (register_form)
12153        {
12154            uint32_t Rm = ReadCoreReg (m, &success);
12155            if (!success)
12156                return false;
12157
12158            operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12159            if (!success)
12160                return false;
12161        }
12162        else
12163        {
12164            operand2 = imm32;
12165        }
12166
12167        uint32_t Rn = ReadCoreReg (n, &success);
12168        if (!success)
12169            return false;
12170
12171        AddWithCarryResult result;
12172
12173        // case opcode of
12174        switch (code)
12175        {
12176            case 0: // when �0000�
12177                // result = R[n] AND operand2; // AND
12178                result.result = Rn & operand2;
12179                break;
12180
12181            case 1: // when �0001�
12182                // result = R[n] EOR operand2; // EOR
12183                result.result = Rn ^ operand2;
12184                break;
12185
12186            case 2: // when �0010�
12187                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12188                result = AddWithCarry (Rn, ~(operand2), 1);
12189                break;
12190
12191            case 3: // when �0011�
12192                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12193                result = AddWithCarry (~(Rn), operand2, 1);
12194                break;
12195
12196            case 4: // when �0100�
12197                // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12198                result = AddWithCarry (Rn, operand2, 0);
12199                break;
12200
12201            case 5: // when �0101�
12202                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12203                result = AddWithCarry (Rn, operand2, APSR_C);
12204                break;
12205
12206            case 6: // when �0110�
12207                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12208                result = AddWithCarry (Rn, ~(operand2), APSR_C);
12209                break;
12210
12211            case 7: // when �0111�
12212                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12213                result = AddWithCarry (~(Rn), operand2, APSR_C);
12214                break;
12215
12216            case 10: // when �1100�
12217                // result = R[n] OR operand2; // ORR
12218                result.result = Rn | operand2;
12219                break;
12220
12221            case 11: // when �1101�
12222                // result = operand2; // MOV
12223                result.result = operand2;
12224                break;
12225
12226            case 12: // when �1110�
12227                // result = R[n] AND NOT(operand2); // BIC
12228                result.result = Rn & ~(operand2);
12229                break;
12230
12231            case 15: // when �1111�
12232                // result = NOT(operand2); // MVN
12233                result.result = ~(operand2);
12234                break;
12235
12236            default:
12237                return false;
12238        }
12239        // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12240
12241        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12242        // the best.
12243        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12244        if (!success)
12245            return false;
12246
12247        CPSRWriteByInstr (spsr, 15, true);
12248
12249        // BranchWritePC(result);
12250        EmulateInstruction::Context context;
12251        context.type = eContextAdjustPC;
12252        context.SetImmediate (result.result);
12253
12254        BranchWritePC (context, result.result);
12255    }
12256    return true;
12257}
12258
12259EmulateInstructionARM::ARMOpcode*
12260EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12261{
12262    static ARMOpcode
12263    g_arm_opcodes[] =
12264    {
12265        //----------------------------------------------------------------------
12266        // Prologue instructions
12267        //----------------------------------------------------------------------
12268
12269        // push register(s)
12270        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12271        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12272
12273        // set r7 to point to a stack offset
12274        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12275        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12276        // copy the stack pointer to ip
12277        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12278        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12279        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12280
12281        // adjust the stack pointer
12282        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12283        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12284
12285        // push one register
12286        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12287        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12288
12289        // vector push consecutive extension register(s)
12290        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12291        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12292
12293        //----------------------------------------------------------------------
12294        // Epilogue instructions
12295        //----------------------------------------------------------------------
12296
12297        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12298        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12299        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12300        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12301
12302        //----------------------------------------------------------------------
12303        // Supervisor Call (previously Software Interrupt)
12304        //----------------------------------------------------------------------
12305        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12306
12307        //----------------------------------------------------------------------
12308        // Branch instructions
12309        //----------------------------------------------------------------------
12310        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12311        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12312        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12313        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12314        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12315        // for example, "bx lr"
12316        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12317        // bxj
12318        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12319
12320        //----------------------------------------------------------------------
12321        // Data-processing instructions
12322        //----------------------------------------------------------------------
12323        // adc (immediate)
12324        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12325        // adc (register)
12326        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12327        // add (immediate)
12328        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12329        // add (register)
12330        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12331        // add (register-shifted register)
12332        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12333        // adr
12334        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12335        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12336        // and (immediate)
12337        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12338        // and (register)
12339        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12340        // bic (immediate)
12341        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12342        // bic (register)
12343        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12344        // eor (immediate)
12345        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12346        // eor (register)
12347        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12348        // orr (immediate)
12349        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12350        // orr (register)
12351        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12352        // rsb (immediate)
12353        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12354        // rsb (register)
12355        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12356        // rsc (immediate)
12357        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12358        // rsc (register)
12359        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12360        // sbc (immediate)
12361        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12362        // sbc (register)
12363        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12364        // sub (immediate, ARM)
12365        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12366        // sub (sp minus immediate)
12367        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12368        // sub (register)
12369        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12370        // teq (immediate)
12371        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12372        // teq (register)
12373        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12374        // tst (immediate)
12375        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12376        // tst (register)
12377        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12378
12379        // mov (immediate)
12380        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12381        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12382        // mov (register)
12383        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12384        // mvn (immediate)
12385        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12386        // mvn (register)
12387        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12388        // cmn (immediate)
12389        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12390        // cmn (register)
12391        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12392        // cmp (immediate)
12393        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12394        // cmp (register)
12395        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12396        // asr (immediate)
12397        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12398        // asr (register)
12399        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12400        // lsl (immediate)
12401        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12402        // lsl (register)
12403        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12404        // lsr (immediate)
12405        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12406        // lsr (register)
12407        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12408        // rrx is a special case encoding of ror (immediate)
12409        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12410        // ror (immediate)
12411        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12412        // ror (register)
12413        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12414        // mul
12415        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12416
12417        // subs pc, lr and related instructions
12418        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12419        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12420
12421        //----------------------------------------------------------------------
12422        // Load instructions
12423        //----------------------------------------------------------------------
12424        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12425        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12426        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12427        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12428        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12429        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12430        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12431        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12432        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12433        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12434        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12435        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12436        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12437        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12438        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12439        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12440        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12441        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12442        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12443        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12444        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12445        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12446        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12447        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12448        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12449
12450        //----------------------------------------------------------------------
12451        // Store instructions
12452        //----------------------------------------------------------------------
12453        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12454        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12455        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12456        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12457        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12458        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12459        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12460        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12461        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12462        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12463        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12464        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12465        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12466        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12467        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12468        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12469        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12470
12471        //----------------------------------------------------------------------
12472        // Other instructions
12473        //----------------------------------------------------------------------
12474        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12475        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12476        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12477        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12478        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12479
12480    };
12481    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12482
12483    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12484    {
12485        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12486            (g_arm_opcodes[i].variants & arm_isa) != 0)
12487            return &g_arm_opcodes[i];
12488    }
12489    return NULL;
12490}
12491
12492
12493EmulateInstructionARM::ARMOpcode*
12494EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12495{
12496
12497    static ARMOpcode
12498    g_thumb_opcodes[] =
12499    {
12500        //----------------------------------------------------------------------
12501        // Prologue instructions
12502        //----------------------------------------------------------------------
12503
12504        // push register(s)
12505        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12506        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12507        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12508
12509        // set r7 to point to a stack offset
12510        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12511        // copy the stack pointer to r7
12512        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12513        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12514        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12515
12516        // PC-relative load into register (see also EmulateADDSPRm)
12517        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12518
12519        // adjust the stack pointer
12520        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12521        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12522        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12523        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12524        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12525
12526        // vector push consecutive extension register(s)
12527        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12528        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12529
12530        //----------------------------------------------------------------------
12531        // Epilogue instructions
12532        //----------------------------------------------------------------------
12533
12534        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12535        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12536        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12537        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12538        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12539        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12540        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12541
12542        //----------------------------------------------------------------------
12543        // Supervisor Call (previously Software Interrupt)
12544        //----------------------------------------------------------------------
12545        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12546
12547        //----------------------------------------------------------------------
12548        // If Then makes up to four following instructions conditional.
12549        //----------------------------------------------------------------------
12550        // The next 5 opcode _must_ come before the if then instruction
12551        { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12552        { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12553        { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12554        { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12555        { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12556        { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12557
12558        //----------------------------------------------------------------------
12559        // Branch instructions
12560        //----------------------------------------------------------------------
12561        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12562        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12563        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12564        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12565        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12566        // J1 == J2 == 1
12567        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12568        // J1 == J2 == 1
12569        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12570        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12571        // for example, "bx lr"
12572        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12573        // bxj
12574        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12575        // compare and branch
12576        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12577        // table branch byte
12578        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12579        // table branch halfword
12580        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12581
12582        //----------------------------------------------------------------------
12583        // Data-processing instructions
12584        //----------------------------------------------------------------------
12585        // adc (immediate)
12586        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12587        // adc (register)
12588        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12589        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12590        // add (register)
12591        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12592        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12593        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12594        // adr
12595        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12596        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12597        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12598        // and (immediate)
12599        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12600        // and (register)
12601        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12602        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12603        // bic (immediate)
12604        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12605        // bic (register)
12606        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12607        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12608        // eor (immediate)
12609        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12610        // eor (register)
12611        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12612        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12613        // orr (immediate)
12614        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12615        // orr (register)
12616        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12617        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12618        // rsb (immediate)
12619        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12620        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12621        // rsb (register)
12622        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12623        // sbc (immediate)
12624        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12625        // sbc (register)
12626        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12627        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12628        // add (immediate, Thumb)
12629        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12630        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12631        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12632        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12633        // sub (immediate, Thumb)
12634        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12635        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12636        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12637        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12638        // sub (sp minus immediate)
12639        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12640        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12641        // sub (register)
12642        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12643        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12644        // teq (immediate)
12645        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12646        // teq (register)
12647        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12648        // tst (immediate)
12649        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12650        // tst (register)
12651        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12652        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12653
12654
12655        // move from high register to high register
12656        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12657        // move from low register to low register
12658        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12659        // mov{s}<c>.w <Rd>, <Rm>
12660        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12661        // move immediate
12662        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12663        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12664        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12665        // mvn (immediate)
12666        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12667        // mvn (register)
12668        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12669        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12670        // cmn (immediate)
12671        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12672        // cmn (register)
12673        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12674        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12675        // cmp (immediate)
12676        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12677        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12678        // cmp (register) (Rn and Rm both from r0-r7)
12679        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12680        // cmp (register) (Rn and Rm not both from r0-r7)
12681        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12682        // asr (immediate)
12683        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12684        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12685        // asr (register)
12686        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12687        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12688        // lsl (immediate)
12689        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12690        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12691        // lsl (register)
12692        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12693        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12694        // lsr (immediate)
12695        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12696        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12697        // lsr (register)
12698        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12699        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12700        // rrx is a special case encoding of ror (immediate)
12701        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12702        // ror (immediate)
12703        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12704        // ror (register)
12705        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12706        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12707        // mul
12708        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12709        // mul
12710        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12711
12712        // subs pc, lr and related instructions
12713        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12714
12715        //----------------------------------------------------------------------
12716        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12717        // otherwise the wrong instructions will be selected.
12718        //----------------------------------------------------------------------
12719
12720        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12721        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12722
12723        //----------------------------------------------------------------------
12724        // Load instructions
12725        //----------------------------------------------------------------------
12726        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12727        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12728        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12729        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12730        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12731        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12732        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12733                  // Thumb2 PC-relative load into register
12734        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12735        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12736        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12737        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12738        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12739        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12740        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12741        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12742        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12743        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12744        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12745        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12746        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12747        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12748        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12749        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12750        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12751        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12752        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12753        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12754        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12755        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12756        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12757        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12758        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12759        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12760        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12761        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12762        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12763        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12764        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12765        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12766        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12767
12768        //----------------------------------------------------------------------
12769        // Store instructions
12770        //----------------------------------------------------------------------
12771        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12772        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12773        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12774        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12775        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12776        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12777        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12778        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12779        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12780        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12781        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12782        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12783        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12784        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12785        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12786        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12787        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12788        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12789        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12790        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12791        { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12792        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12793
12794        //----------------------------------------------------------------------
12795        // Other instructions
12796        //----------------------------------------------------------------------
12797        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12798        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12799        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12800        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12801        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12802        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12803        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12804        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12805    };
12806
12807    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12808    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12809    {
12810        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12811            (g_thumb_opcodes[i].variants & arm_isa) != 0)
12812            return &g_thumb_opcodes[i];
12813    }
12814    return NULL;
12815}
12816
12817bool
12818EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12819{
12820    m_arch = arch;
12821    m_arm_isa = 0;
12822    const char *arch_cstr = arch.GetArchitectureName ();
12823    if (arch_cstr)
12824    {
12825        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12826        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12827        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12828        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12829        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12830        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12831        else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12832        else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12833        else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12834        else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12835        else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12836        else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12837        else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12838    }
12839    return m_arm_isa != 0;
12840}
12841
12842bool
12843EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12844{
12845    if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12846    {
12847        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12848            m_opcode_mode = eModeThumb;
12849        else
12850        {
12851            AddressClass addr_class = inst_addr.GetAddressClass();
12852
12853            if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12854                m_opcode_mode = eModeARM;
12855            else if (addr_class == eAddressClassCodeAlternateISA)
12856                m_opcode_mode = eModeThumb;
12857            else
12858                return false;
12859        }
12860        if (m_opcode_mode == eModeThumb)
12861            m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12862        else
12863            m_opcode_cpsr = CPSR_MODE_USR;
12864        return true;
12865    }
12866    return false;
12867}
12868
12869bool
12870EmulateInstructionARM::ReadInstruction ()
12871{
12872    bool success = false;
12873    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12874    if (success)
12875    {
12876        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12877        if (success)
12878        {
12879            Context read_inst_context;
12880            read_inst_context.type = eContextReadOpcode;
12881            read_inst_context.SetNoArgs ();
12882
12883            if (m_opcode_cpsr & MASK_CPSR_T)
12884            {
12885                m_opcode_mode = eModeThumb;
12886                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12887
12888                if (success)
12889                {
12890                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12891                    {
12892                        m_opcode.SetOpcode16 (thumb_opcode);
12893                    }
12894                    else
12895                    {
12896                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12897                    }
12898                }
12899            }
12900            else
12901            {
12902                m_opcode_mode = eModeARM;
12903                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12904            }
12905        }
12906    }
12907    if (!success)
12908    {
12909        m_opcode_mode = eModeInvalid;
12910        m_addr = LLDB_INVALID_ADDRESS;
12911    }
12912    return success;
12913}
12914
12915uint32_t
12916EmulateInstructionARM::ArchVersion ()
12917{
12918    return m_arm_isa;
12919}
12920
12921bool
12922EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12923{
12924   // If we are ignoring conditions, then always return true.
12925   // this allows us to iterate over disassembly code and still
12926   // emulate an instruction even if we don't have all the right
12927   // bits set in the CPSR register...
12928    if (m_ignore_conditions)
12929        return true;
12930
12931    if (is_conditional)
12932        *is_conditional = true;
12933
12934    const uint32_t cond = CurrentCond (opcode);
12935
12936    if (cond == UINT32_MAX)
12937        return false;
12938
12939    bool result = false;
12940    switch (UnsignedBits(cond, 3, 1))
12941    {
12942    case 0:
12943		if (m_opcode_cpsr == 0)
12944			result = true;
12945        else
12946            result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12947		break;
12948    case 1:
12949        if (m_opcode_cpsr == 0)
12950            result = true;
12951        else
12952            result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12953		break;
12954    case 2:
12955        if (m_opcode_cpsr == 0)
12956            result = true;
12957        else
12958            result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12959		break;
12960    case 3:
12961        if (m_opcode_cpsr == 0)
12962            result = true;
12963        else
12964            result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12965		break;
12966    case 4:
12967        if (m_opcode_cpsr == 0)
12968            result = true;
12969        else
12970            result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12971		break;
12972    case 5:
12973        if (m_opcode_cpsr == 0)
12974            result = true;
12975        else
12976		{
12977            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12978            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12979            result = n == v;
12980        }
12981        break;
12982    case 6:
12983        if (m_opcode_cpsr == 0)
12984            result = true;
12985        else
12986		{
12987            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12988            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12989            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12990        }
12991        break;
12992    case 7:
12993        // Always execute (cond == 0b1110, or the special 0b1111 which gives
12994        // opcodes different meanings, but always means execution happpens.
12995        if (is_conditional)
12996            *is_conditional = false;
12997        result = true;
12998        break;
12999    }
13000
13001    if (cond & 1)
13002        result = !result;
13003    return result;
13004}
13005
13006uint32_t
13007EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13008{
13009    switch (m_opcode_mode)
13010    {
13011    case eModeInvalid:
13012        break;
13013
13014    case eModeARM:
13015        return UnsignedBits(opcode, 31, 28);
13016
13017    case eModeThumb:
13018        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13019        // 'cond' field of the encoding.
13020        {
13021            const uint32_t byte_size = m_opcode.GetByteSize();
13022            if (byte_size == 2)
13023            {
13024                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13025                    return Bits32(opcode, 11, 7);
13026            }
13027            else if (byte_size == 4)
13028            {
13029                if (Bits32(opcode, 31, 27) == 0x1e &&
13030                    Bits32(opcode, 15, 14) == 0x02 &&
13031                    Bits32(opcode, 12, 12) == 0x00 &&
13032                    Bits32(opcode, 25, 22) <= 0x0d)
13033                {
13034                    return Bits32(opcode, 25, 22);
13035                }
13036            }
13037            else
13038                // We have an invalid thumb instruction, let's bail out.
13039                break;
13040
13041            return m_it_session.GetCond();
13042        }
13043    }
13044    return UINT32_MAX;  // Return invalid value
13045}
13046
13047bool
13048EmulateInstructionARM::InITBlock()
13049{
13050    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13051}
13052
13053bool
13054EmulateInstructionARM::LastInITBlock()
13055{
13056    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13057}
13058
13059bool
13060EmulateInstructionARM::BadMode (uint32_t mode)
13061{
13062
13063    switch (mode)
13064    {
13065        case 16: return false; // '10000'
13066        case 17: return false; // '10001'
13067        case 18: return false; // '10010'
13068        case 19: return false; // '10011'
13069        case 22: return false; // '10110'
13070        case 23: return false; // '10111'
13071        case 27: return false; // '11011'
13072        case 31: return false; // '11111'
13073        default: return true;
13074    }
13075    return true;
13076}
13077
13078bool
13079EmulateInstructionARM::CurrentModeIsPrivileged ()
13080{
13081    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13082
13083    if (BadMode (mode))
13084        return false;
13085
13086    if (mode == 16)
13087        return false;
13088
13089    return true;
13090}
13091
13092void
13093EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13094{
13095    bool privileged = CurrentModeIsPrivileged();
13096
13097    uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13098
13099    if (BitIsSet (bytemask, 3))
13100    {
13101        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13102        if (affect_execstate)
13103            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13104    }
13105
13106    if (BitIsSet (bytemask, 2))
13107    {
13108        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13109    }
13110
13111    if (BitIsSet (bytemask, 1))
13112    {
13113        if (affect_execstate)
13114            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13115        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13116        if (privileged)
13117            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13118    }
13119
13120    if (BitIsSet (bytemask, 0))
13121    {
13122        if (privileged)
13123            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13124        if (affect_execstate)
13125            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13126        if (privileged)
13127            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13128    }
13129
13130    m_opcode_cpsr = tmp_cpsr;
13131}
13132
13133
13134bool
13135EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13136{
13137    addr_t target;
13138
13139    // Check the current instruction set.
13140    if (CurrentInstrSet() == eModeARM)
13141        target = addr & 0xfffffffc;
13142    else
13143        target = addr & 0xfffffffe;
13144
13145    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13146        return false;
13147
13148    return true;
13149}
13150
13151// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13152bool
13153EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13154{
13155    addr_t target;
13156    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13157    // we want to record it and issue a WriteRegister callback so the clients
13158    // can track the mode changes accordingly.
13159    bool cpsr_changed = false;
13160
13161    if (BitIsSet(addr, 0))
13162    {
13163        if (CurrentInstrSet() != eModeThumb)
13164        {
13165            SelectInstrSet(eModeThumb);
13166            cpsr_changed = true;
13167        }
13168        target = addr & 0xfffffffe;
13169        context.SetISA (eModeThumb);
13170    }
13171    else if (BitIsClear(addr, 1))
13172    {
13173        if (CurrentInstrSet() != eModeARM)
13174        {
13175            SelectInstrSet(eModeARM);
13176            cpsr_changed = true;
13177        }
13178        target = addr & 0xfffffffc;
13179        context.SetISA (eModeARM);
13180    }
13181    else
13182        return false; // address<1:0> == '10' => UNPREDICTABLE
13183
13184    if (cpsr_changed)
13185    {
13186        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13187            return false;
13188    }
13189    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13190        return false;
13191
13192    return true;
13193}
13194
13195// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13196bool
13197EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13198{
13199    if (ArchVersion() >= ARMv5T)
13200        return BXWritePC(context, addr);
13201    else
13202        return BranchWritePC((const Context)context, addr);
13203}
13204
13205// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13206bool
13207EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13208{
13209    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13210        return BXWritePC(context, addr);
13211    else
13212        return BranchWritePC((const Context)context, addr);
13213}
13214
13215EmulateInstructionARM::Mode
13216EmulateInstructionARM::CurrentInstrSet ()
13217{
13218    return m_opcode_mode;
13219}
13220
13221// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13222// ReadInstruction() is performed.  This function has a side effect of updating
13223// the m_new_inst_cpsr member variable if necessary.
13224bool
13225EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13226{
13227    m_new_inst_cpsr = m_opcode_cpsr;
13228    switch (arm_or_thumb)
13229    {
13230    default:
13231        return false;
13232    case eModeARM:
13233        // Clear the T bit.
13234        m_new_inst_cpsr &= ~MASK_CPSR_T;
13235        break;
13236    case eModeThumb:
13237        // Set the T bit.
13238        m_new_inst_cpsr |= MASK_CPSR_T;
13239        break;
13240    }
13241    return true;
13242}
13243
13244// This function returns TRUE if the processor currently provides support for
13245// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13246// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13247bool
13248EmulateInstructionARM::UnalignedSupport()
13249{
13250    return (ArchVersion() >= ARMv7);
13251}
13252
13253// The main addition and subtraction instructions can produce status information
13254// about both unsigned carry and signed overflow conditions.  This status
13255// information can be used to synthesize multi-word additions and subtractions.
13256EmulateInstructionARM::AddWithCarryResult
13257EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13258{
13259    uint32_t result;
13260    uint8_t carry_out;
13261    uint8_t overflow;
13262
13263    uint64_t unsigned_sum = x + y + carry_in;
13264    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13265
13266    result = UnsignedBits(unsigned_sum, 31, 0);
13267//    carry_out = (result == unsigned_sum ? 0 : 1);
13268    overflow = ((int32_t)result == signed_sum ? 0 : 1);
13269
13270    if (carry_in)
13271        carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13272    else
13273        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13274
13275    AddWithCarryResult res = { result, carry_out, overflow };
13276    return res;
13277}
13278
13279uint32_t
13280EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13281{
13282    uint32_t reg_kind, reg_num;
13283    switch (num)
13284    {
13285    case SP_REG:
13286        reg_kind = eRegisterKindGeneric;
13287        reg_num  = LLDB_REGNUM_GENERIC_SP;
13288        break;
13289    case LR_REG:
13290        reg_kind = eRegisterKindGeneric;
13291        reg_num  = LLDB_REGNUM_GENERIC_RA;
13292        break;
13293    case PC_REG:
13294        reg_kind = eRegisterKindGeneric;
13295        reg_num  = LLDB_REGNUM_GENERIC_PC;
13296        break;
13297    default:
13298        if (num < SP_REG)
13299        {
13300            reg_kind = eRegisterKindDWARF;
13301            reg_num  = dwarf_r0 + num;
13302        }
13303        else
13304        {
13305            //assert(0 && "Invalid register number");
13306            *success = false;
13307            return UINT32_MAX;
13308        }
13309        break;
13310    }
13311
13312    // Read our register.
13313    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13314
13315    // When executing an ARM instruction , PC reads as the address of the current
13316    // instruction plus 8.
13317    // When executing a Thumb instruction , PC reads as the address of the current
13318    // instruction plus 4.
13319    if (num == 15)
13320    {
13321        if (CurrentInstrSet() == eModeARM)
13322            val += 8;
13323        else
13324            val += 4;
13325    }
13326
13327    return val;
13328}
13329
13330// Write the result to the ARM core register Rd, and optionally update the
13331// condition flags based on the result.
13332//
13333// This helper method tries to encapsulate the following pseudocode from the
13334// ARM Architecture Reference Manual:
13335//
13336// if d == 15 then         // Can only occur for encoding A1
13337//     ALUWritePC(result); // setflags is always FALSE here
13338// else
13339//     R[d] = result;
13340//     if setflags then
13341//         APSR.N = result<31>;
13342//         APSR.Z = IsZeroBit(result);
13343//         APSR.C = carry;
13344//         // APSR.V unchanged
13345//
13346// In the above case, the API client does not pass in the overflow arg, which
13347// defaults to ~0u.
13348bool
13349EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13350                                                  const uint32_t result,
13351                                                  const uint32_t Rd,
13352                                                  bool setflags,
13353                                                  const uint32_t carry,
13354                                                  const uint32_t overflow)
13355{
13356    if (Rd == 15)
13357    {
13358        if (!ALUWritePC (context, result))
13359            return false;
13360    }
13361    else
13362    {
13363        uint32_t reg_kind, reg_num;
13364        switch (Rd)
13365        {
13366        case SP_REG:
13367            reg_kind = eRegisterKindGeneric;
13368            reg_num  = LLDB_REGNUM_GENERIC_SP;
13369            break;
13370        case LR_REG:
13371            reg_kind = eRegisterKindGeneric;
13372            reg_num  = LLDB_REGNUM_GENERIC_RA;
13373            break;
13374        default:
13375            reg_kind = eRegisterKindDWARF;
13376            reg_num  = dwarf_r0 + Rd;
13377        }
13378        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13379            return false;
13380        if (setflags)
13381            return WriteFlags (context, result, carry, overflow);
13382    }
13383    return true;
13384}
13385
13386// This helper method tries to encapsulate the following pseudocode from the
13387// ARM Architecture Reference Manual:
13388//
13389// APSR.N = result<31>;
13390// APSR.Z = IsZeroBit(result);
13391// APSR.C = carry;
13392// APSR.V = overflow
13393//
13394// Default arguments can be specified for carry and overflow parameters, which means
13395// not to update the respective flags.
13396bool
13397EmulateInstructionARM::WriteFlags (Context &context,
13398                                   const uint32_t result,
13399                                   const uint32_t carry,
13400                                   const uint32_t overflow)
13401{
13402    m_new_inst_cpsr = m_opcode_cpsr;
13403    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13404    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13405    if (carry != ~0u)
13406        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13407    if (overflow != ~0u)
13408        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13409    if (m_new_inst_cpsr != m_opcode_cpsr)
13410    {
13411        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13412            return false;
13413    }
13414    return true;
13415}
13416
13417bool
13418EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13419{
13420    // Advance the ITSTATE bits to their values for the next instruction.
13421    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13422        m_it_session.ITAdvance();
13423
13424    ARMOpcode *opcode_data = NULL;
13425
13426    if (m_opcode_mode == eModeThumb)
13427        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13428    else if (m_opcode_mode == eModeARM)
13429        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13430
13431    if (opcode_data == NULL)
13432        return false;
13433
13434    const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13435    m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13436
13437    bool success = false;
13438    if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13439    {
13440        m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13441                                                dwarf_cpsr,
13442                                                0,
13443                                                &success);
13444    }
13445
13446    // Only return false if we are unable to read the CPSR if we care about conditions
13447    if (success == false && m_ignore_conditions == false)
13448        return false;
13449
13450    uint32_t orig_pc_value = 0;
13451    if (auto_advance_pc)
13452    {
13453        orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13454        if (!success)
13455            return false;
13456    }
13457
13458    // Call the Emulate... function.
13459    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13460    if (!success)
13461        return false;
13462
13463    if (auto_advance_pc)
13464    {
13465        uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13466        if (!success)
13467            return false;
13468
13469        if (auto_advance_pc && (after_pc_value == orig_pc_value))
13470        {
13471            if (opcode_data->size == eSize32)
13472                after_pc_value += 4;
13473            else if (opcode_data->size == eSize16)
13474                after_pc_value += 2;
13475
13476            EmulateInstruction::Context context;
13477            context.type = eContextAdvancePC;
13478            context.SetNoArgs();
13479            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13480                return false;
13481
13482        }
13483    }
13484    return true;
13485}
13486
13487bool
13488EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13489{
13490    if (!test_data)
13491    {
13492        out_stream->Printf ("TestEmulation: Missing test data.\n");
13493        return false;
13494    }
13495
13496    static ConstString opcode_key ("opcode");
13497    static ConstString before_key ("before_state");
13498    static ConstString after_key ("after_state");
13499
13500    OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13501
13502    uint32_t test_opcode;
13503    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13504    {
13505        out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13506        return false;
13507    }
13508    test_opcode = value_sp->GetUInt64Value ();
13509
13510    if (arch.GetTriple().getArch() == llvm::Triple::arm)
13511    {
13512        m_opcode_mode = eModeARM;
13513        m_opcode.SetOpcode32 (test_opcode);
13514    }
13515    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13516    {
13517        m_opcode_mode = eModeThumb;
13518        if (test_opcode < 0x10000)
13519            m_opcode.SetOpcode16 (test_opcode);
13520        else
13521            m_opcode.SetOpcode32 (test_opcode);
13522
13523    }
13524    else
13525    {
13526        out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13527        return false;
13528    }
13529
13530    EmulationStateARM before_state;
13531    EmulationStateARM after_state;
13532
13533    value_sp = test_data->GetValueForKey (before_key);
13534    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13535    {
13536        out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13537        return false;
13538    }
13539
13540    OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13541    if (!before_state.LoadStateFromDictionary (state_dictionary))
13542    {
13543        out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13544        return false;
13545    }
13546
13547    value_sp = test_data->GetValueForKey (after_key);
13548    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13549    {
13550        out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13551        return false;
13552    }
13553
13554    state_dictionary = value_sp->GetAsDictionary ();
13555    if (!after_state.LoadStateFromDictionary (state_dictionary))
13556    {
13557        out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13558        return false;
13559    }
13560
13561    SetBaton ((void *) &before_state);
13562    SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13563                  &EmulationStateARM::WritePseudoMemory,
13564                  &EmulationStateARM::ReadPseudoRegister,
13565                  &EmulationStateARM::WritePseudoRegister);
13566
13567    bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13568    if (!success)
13569    {
13570        out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13571        return false;
13572    }
13573
13574    success = before_state.CompareState (after_state);
13575    if (!success)
13576        out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13577
13578    return success;
13579}
13580//
13581//
13582//const char *
13583//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13584//{
13585//    if (reg_kind == eRegisterKindGeneric)
13586//    {
13587//        switch (reg_num)
13588//        {
13589//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13590//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13591//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13592//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13593//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13594//        default: return NULL;
13595//        }
13596//    }
13597//    else if (reg_kind == eRegisterKindDWARF)
13598//    {
13599//        return GetARMDWARFRegisterName (reg_num);
13600//    }
13601//    return NULL;
13602//}
13603//
13604bool
13605EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13606{
13607    unwind_plan.Clear();
13608    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13609
13610    UnwindPlan::RowSP row(new UnwindPlan::Row);
13611
13612    // Our previous Call Frame Address is the stack pointer
13613    row->SetCFARegister (dwarf_sp);
13614
13615    // Our previous PC is in the LR
13616    row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13617    unwind_plan.AppendRow (row);
13618
13619    // All other registers are the same.
13620
13621    unwind_plan.SetSourceName ("EmulateInstructionARM");
13622    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13623    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13624    return true;
13625}
13626