EmulateInstructionARM.cpp revision dfb2e20724a90a4a10558ddaee18b72a1c51e499
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
20#include "Plugins/Process/Utility/ARMDefines.h"
21#include "Plugins/Process/Utility/ARMUtils.h"
22#include "Utility/ARM_DWARF_Registers.h"
23
24#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
25                                     // and CountTrailingZeros_32 function
26
27using namespace lldb;
28using namespace lldb_private;
29
30// Convenient macro definitions.
31#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
32#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
33
34#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
35
36//----------------------------------------------------------------------
37//
38// ITSession implementation
39//
40//----------------------------------------------------------------------
41
42// A8.6.50
43// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
44static unsigned short CountITSize(unsigned ITMask) {
45    // First count the trailing zeros of the IT mask.
46    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
47    if (TZ > 3)
48    {
49        printf("Encoding error: IT Mask '0000'\n");
50        return 0;
51    }
52    return (4 - TZ);
53}
54
55// Init ITState.  Note that at least one bit is always 1 in mask.
56bool ITSession::InitIT(unsigned short bits7_0)
57{
58    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
59    if (ITCounter == 0)
60        return false;
61
62    // A8.6.50 IT
63    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
64    if (FirstCond == 0xF)
65    {
66        printf("Encoding error: IT FirstCond '1111'\n");
67        return false;
68    }
69    if (FirstCond == 0xE && ITCounter != 1)
70    {
71        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
72        return false;
73    }
74
75    ITState = bits7_0;
76    return true;
77}
78
79// Update ITState if necessary.
80void ITSession::ITAdvance()
81{
82    assert(ITCounter);
83    --ITCounter;
84    if (ITCounter == 0)
85        ITState = 0;
86    else
87    {
88        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
89        SetBits32(ITState, 4, 0, NewITState4_0);
90    }
91}
92
93// Return true if we're inside an IT Block.
94bool ITSession::InITBlock()
95{
96    return ITCounter != 0;
97}
98
99// Return true if we're the last instruction inside an IT Block.
100bool ITSession::LastInITBlock()
101{
102    return ITCounter == 1;
103}
104
105// Get condition bits for the current thumb instruction.
106uint32_t ITSession::GetCond()
107{
108    if (InITBlock())
109        return Bits32(ITState, 7, 4);
110    else
111        return COND_AL;
112}
113
114// ARM constants used during decoding
115#define REG_RD          0
116#define LDM_REGLIST     1
117#define SP_REG          13
118#define LR_REG          14
119#define PC_REG          15
120#define PC_REGLIST_BIT  0x8000
121
122#define ARMv4     (1u << 0)
123#define ARMv4T    (1u << 1)
124#define ARMv5T    (1u << 2)
125#define ARMv5TE   (1u << 3)
126#define ARMv5TEJ  (1u << 4)
127#define ARMv6     (1u << 5)
128#define ARMv6K    (1u << 6)
129#define ARMv6T2   (1u << 7)
130#define ARMv7     (1u << 8)
131#define ARMv8     (1u << 9)
132#define ARMvAll   (0xffffffffu)
133
134#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
135#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
136#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
137#define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
138#define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
139#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
140
141#define No_VFP  0
142#define VFPv1   (1u << 1)
143#define VFPv2   (1u << 2)
144#define VFPv3   (1u << 3)
145#define AdvancedSIMD (1u << 4)
146
147#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
148#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
149#define VFPv2v3     (VFPv2 | VFPv3)
150
151//----------------------------------------------------------------------
152//
153// EmulateInstructionARM implementation
154//
155//----------------------------------------------------------------------
156
157void
158EmulateInstructionARM::Initialize ()
159{
160    PluginManager::RegisterPlugin (GetPluginNameStatic (),
161                                   GetPluginDescriptionStatic (),
162                                   CreateInstance);
163}
164
165void
166EmulateInstructionARM::Terminate ()
167{
168    PluginManager::UnregisterPlugin (CreateInstance);
169}
170
171const char *
172EmulateInstructionARM::GetPluginNameStatic ()
173{
174    return "lldb.emulate-instruction.arm";
175}
176
177const char *
178EmulateInstructionARM::GetPluginDescriptionStatic ()
179{
180    return "Emulate instructions for the ARM architecture.";
181}
182
183EmulateInstruction *
184EmulateInstructionARM::CreateInstance (const ArchSpec &arch)
185{
186    if (arch.GetTriple().getArch() == llvm::Triple::arm)
187    {
188        std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
189
190        if (emulate_insn_ap.get())
191            return emulate_insn_ap.release();
192    }
193    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
194    {
195        std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
196
197        if (emulate_insn_ap.get())
198            return emulate_insn_ap.release();
199    }
200
201    return NULL;
202}
203
204bool
205EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
206{
207    if (arch.GetTriple().getArch () == llvm::Triple::arm)
208        return true;
209    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
210        return true;
211
212    return false;
213}
214
215// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
216bool
217EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
218{
219    EmulateInstruction::Context context;
220    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
221    context.SetNoArgs ();
222
223    uint32_t random_data = rand ();
224    const uint32_t addr_byte_size = GetAddressByteSize();
225
226    if (!MemAWrite (context, address, random_data, addr_byte_size))
227        return false;
228
229    return true;
230}
231
232// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
233bool
234EmulateInstructionARM::WriteBits32Unknown (int n)
235{
236    EmulateInstruction::Context context;
237    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
238    context.SetNoArgs ();
239
240    bool success;
241    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
242
243    if (!success)
244        return false;
245
246    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
247        return false;
248
249    return true;
250}
251
252// Push Multiple Registers stores multiple registers to the stack, storing to
253// consecutive memory locations ending just below the address in SP, and updates
254// SP to point to the start of the stored data.
255bool
256EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
257{
258#if 0
259    // ARM pseudo code...
260    if (ConditionPassed())
261    {
262        EncodingSpecificOperations();
263        NullCheckIfThumbEE(13);
264        address = SP - 4*BitCount(registers);
265
266        for (i = 0 to 14)
267        {
268            if (registers<i> == '1')
269            {
270                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
271                    MemA[address,4] = bits(32) UNKNOWN;
272                else
273                    MemA[address,4] = R[i];
274                address = address + 4;
275            }
276        }
277
278        if (registers<15> == '1') // Only possible for encoding A1 or A2
279            MemA[address,4] = PCStoreValue();
280
281        SP = SP - 4*BitCount(registers);
282    }
283#endif
284
285    bool success = false;
286    if (ConditionPassed(opcode))
287    {
288        const uint32_t addr_byte_size = GetAddressByteSize();
289        const addr_t sp = ReadCoreReg (SP_REG, &success);
290        if (!success)
291            return false;
292        uint32_t registers = 0;
293        uint32_t Rt; // the source register
294        switch (encoding) {
295        case eEncodingT1:
296            registers = Bits32(opcode, 7, 0);
297            // The M bit represents LR.
298            if (Bit32(opcode, 8))
299                registers |= (1u << 14);
300            // if BitCount(registers) < 1 then UNPREDICTABLE;
301            if (BitCount(registers) < 1)
302                return false;
303            break;
304        case eEncodingT2:
305            // Ignore bits 15 & 13.
306            registers = Bits32(opcode, 15, 0) & ~0xa000;
307            // if BitCount(registers) < 2 then UNPREDICTABLE;
308            if (BitCount(registers) < 2)
309                return false;
310            break;
311        case eEncodingT3:
312            Rt = Bits32(opcode, 15, 12);
313            // if BadReg(t) then UNPREDICTABLE;
314            if (BadReg(Rt))
315                return false;
316            registers = (1u << Rt);
317            break;
318        case eEncodingA1:
319            registers = Bits32(opcode, 15, 0);
320            // Instead of return false, let's handle the following case as well,
321            // which amounts to pushing one reg onto the full descending stacks.
322            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
323            break;
324        case eEncodingA2:
325            Rt = Bits32(opcode, 15, 12);
326            // if t == 13 then UNPREDICTABLE;
327            if (Rt == dwarf_sp)
328                return false;
329            registers = (1u << Rt);
330            break;
331        default:
332            return false;
333        }
334        addr_t sp_offset = addr_byte_size * BitCount (registers);
335        addr_t addr = sp - sp_offset;
336        uint32_t i;
337
338        EmulateInstruction::Context context;
339        context.type = EmulateInstruction::eContextPushRegisterOnStack;
340        Register dwarf_reg;
341        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
342        Register sp_reg;
343        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
344        for (i=0; i<15; ++i)
345        {
346            if (BitIsSet (registers, i))
347            {
348                dwarf_reg.num = dwarf_r0 + i;
349                context.SetRegisterToRegisterPlusOffset (dwarf_reg, sp_reg, addr - sp);
350                uint32_t reg_value = ReadCoreReg(i, &success);
351                if (!success)
352                    return false;
353                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
354                    return false;
355                addr += addr_byte_size;
356            }
357        }
358
359        if (BitIsSet (registers, 15))
360        {
361            dwarf_reg.num = dwarf_pc;
362            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
363            const uint32_t pc = ReadCoreReg(PC_REG, &success);
364            if (!success)
365                return false;
366            if (!MemAWrite (context, addr, pc, addr_byte_size))
367                return false;
368        }
369
370        context.type = EmulateInstruction::eContextAdjustStackPointer;
371        context.SetImmediateSigned (-sp_offset);
372
373        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
374            return false;
375    }
376    return true;
377}
378
379// Pop Multiple Registers loads multiple registers from the stack, loading from
380// consecutive memory locations staring at the address in SP, and updates
381// SP to point just above the loaded data.
382bool
383EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
384{
385#if 0
386    // ARM pseudo code...
387    if (ConditionPassed())
388    {
389        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
390        address = SP;
391        for i = 0 to 14
392            if registers<i> == '1' then
393                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
394        if registers<15> == '1' then
395            if UnalignedAllowed then
396                LoadWritePC(MemU[address,4]);
397            else
398                LoadWritePC(MemA[address,4]);
399        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
400        if registers<13> == '1' then SP = bits(32) UNKNOWN;
401    }
402#endif
403
404    bool success = false;
405
406    if (ConditionPassed(opcode))
407    {
408        const uint32_t addr_byte_size = GetAddressByteSize();
409        const addr_t sp = ReadCoreReg (SP_REG, &success);
410        if (!success)
411            return false;
412        uint32_t registers = 0;
413        uint32_t Rt; // the destination register
414        switch (encoding) {
415        case eEncodingT1:
416            registers = Bits32(opcode, 7, 0);
417            // The P bit represents PC.
418            if (Bit32(opcode, 8))
419                registers |= (1u << 15);
420            // if BitCount(registers) < 1 then UNPREDICTABLE;
421            if (BitCount(registers) < 1)
422                return false;
423            break;
424        case eEncodingT2:
425            // Ignore bit 13.
426            registers = Bits32(opcode, 15, 0) & ~0x2000;
427            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
428            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
429                return false;
430            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
431            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
432                return false;
433            break;
434        case eEncodingT3:
435            Rt = Bits32(opcode, 15, 12);
436            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
437            if (Rt == 13)
438                return false;
439            if (Rt == 15 && InITBlock() && !LastInITBlock())
440                return false;
441            registers = (1u << Rt);
442            break;
443        case eEncodingA1:
444            registers = Bits32(opcode, 15, 0);
445            // Instead of return false, let's handle the following case as well,
446            // which amounts to popping one reg from the full descending stacks.
447            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
448
449            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
450            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
451                return false;
452            break;
453        case eEncodingA2:
454            Rt = Bits32(opcode, 15, 12);
455            // if t == 13 then UNPREDICTABLE;
456            if (Rt == dwarf_sp)
457                return false;
458            registers = (1u << Rt);
459            break;
460        default:
461            return false;
462        }
463        addr_t sp_offset = addr_byte_size * BitCount (registers);
464        addr_t addr = sp;
465        uint32_t i, data;
466
467        EmulateInstruction::Context context;
468        context.type = EmulateInstruction::eContextPopRegisterOffStack;
469        Register dwarf_reg;
470        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
471        Register sp_reg;
472        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
473        for (i=0; i<15; ++i)
474        {
475            if (BitIsSet (registers, i))
476            {
477                dwarf_reg.num = dwarf_r0 + i;
478                context.SetRegisterPlusOffset (sp_reg, addr - sp);
479                data = MemARead(context, addr, 4, 0, &success);
480                if (!success)
481                    return false;
482                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
483                    return false;
484                addr += addr_byte_size;
485            }
486        }
487
488        if (BitIsSet (registers, 15))
489        {
490            dwarf_reg.num = dwarf_pc;
491            context.SetRegisterPlusOffset (sp_reg, addr - sp);
492            data = MemARead(context, addr, 4, 0, &success);
493            if (!success)
494                return false;
495            // In ARMv5T and above, this is an interworking branch.
496            if (!LoadWritePC(context, data))
497                return false;
498            addr += addr_byte_size;
499        }
500
501        context.type = EmulateInstruction::eContextAdjustStackPointer;
502        context.SetImmediateSigned (sp_offset);
503
504        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
505            return false;
506    }
507    return true;
508}
509
510// Set r7 or ip to point to saved value residing within the stack.
511// ADD (SP plus immediate)
512bool
513EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
514{
515#if 0
516    // ARM pseudo code...
517    if (ConditionPassed())
518    {
519        EncodingSpecificOperations();
520        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
521        if d == 15 then
522           ALUWritePC(result); // setflags is always FALSE here
523        else
524            R[d] = result;
525            if setflags then
526                APSR.N = result<31>;
527                APSR.Z = IsZeroBit(result);
528                APSR.C = carry;
529                APSR.V = overflow;
530    }
531#endif
532
533    bool success = false;
534
535    if (ConditionPassed(opcode))
536    {
537        const addr_t sp = ReadCoreReg (SP_REG, &success);
538        if (!success)
539            return false;
540        uint32_t Rd; // the destination register
541        uint32_t imm32;
542        switch (encoding) {
543        case eEncodingT1:
544            Rd = 7;
545            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
546            break;
547        case eEncodingA1:
548            Rd = Bits32(opcode, 15, 12);
549            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
550            break;
551        default:
552            return false;
553        }
554        addr_t sp_offset = imm32;
555        addr_t addr = sp + sp_offset; // a pointer to the stack area
556
557        EmulateInstruction::Context context;
558        context.type = EmulateInstruction::eContextAdjustStackPointer;
559        Register sp_reg;
560        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
561        context.SetRegisterPlusOffset (sp_reg, sp_offset);
562
563        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
564            return false;
565    }
566    return true;
567}
568
569// Set r7 or ip to the current stack pointer.
570// MOV (register)
571bool
572EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
573{
574#if 0
575    // ARM pseudo code...
576    if (ConditionPassed())
577    {
578        EncodingSpecificOperations();
579        result = R[m];
580        if d == 15 then
581            ALUWritePC(result); // setflags is always FALSE here
582        else
583            R[d] = result;
584            if setflags then
585                APSR.N = result<31>;
586                APSR.Z = IsZeroBit(result);
587                // APSR.C unchanged
588                // APSR.V unchanged
589    }
590#endif
591
592    bool success = false;
593
594    if (ConditionPassed(opcode))
595    {
596        const addr_t sp = ReadCoreReg (SP_REG, &success);
597        if (!success)
598            return false;
599        uint32_t Rd; // the destination register
600        switch (encoding) {
601        case eEncodingT1:
602            Rd = 7;
603            break;
604        case eEncodingA1:
605            Rd = 12;
606            break;
607        default:
608            return false;
609        }
610
611        EmulateInstruction::Context context;
612        context.type = EmulateInstruction::eContextRegisterPlusOffset;
613        Register sp_reg;
614        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
615        context.SetRegisterPlusOffset (sp_reg, 0);
616
617        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
618            return false;
619    }
620    return true;
621}
622
623// Move from high register (r8-r15) to low register (r0-r7).
624// MOV (register)
625bool
626EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
627{
628    return EmulateMOVRdRm (opcode, encoding);
629}
630
631// Move from register to register.
632// MOV (register)
633bool
634EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
635{
636#if 0
637    // ARM pseudo code...
638    if (ConditionPassed())
639    {
640        EncodingSpecificOperations();
641        result = R[m];
642        if d == 15 then
643            ALUWritePC(result); // setflags is always FALSE here
644        else
645            R[d] = result;
646            if setflags then
647                APSR.N = result<31>;
648                APSR.Z = IsZeroBit(result);
649                // APSR.C unchanged
650                // APSR.V unchanged
651    }
652#endif
653
654    bool success = false;
655
656    if (ConditionPassed(opcode))
657    {
658        uint32_t Rm; // the source register
659        uint32_t Rd; // the destination register
660        bool setflags;
661        switch (encoding) {
662        case eEncodingT1:
663            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
664            Rm = Bits32(opcode, 6, 3);
665            setflags = false;
666            if (Rd == 15 && InITBlock() && !LastInITBlock())
667                return false;
668            break;
669        case eEncodingT2:
670            Rd = Bits32(opcode, 2, 0);
671            Rm = Bits32(opcode, 5, 3);
672            setflags = true;
673            if (InITBlock())
674                return false;
675            break;
676        case eEncodingT3:
677            Rd = Bits32(opcode, 11, 8);
678            Rm = Bits32(opcode, 3, 0);
679            setflags = BitIsSet(opcode, 20);
680            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
681            if (setflags && (BadReg(Rd) || BadReg(Rm)))
682                return false;
683            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
684            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
685                return false;
686            break;
687        case eEncodingA1:
688            Rd = Bits32(opcode, 15, 12);
689            Rm = Bits32(opcode, 3, 0);
690            setflags = BitIsSet(opcode, 20);
691
692            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
693            if (Rd == 15 && setflags)
694                return EmulateSUBSPcLrEtc (opcode, encoding);
695            break;
696        default:
697            return false;
698        }
699        uint32_t result = ReadCoreReg(Rm, &success);
700        if (!success)
701            return false;
702
703        // The context specifies that Rm is to be moved into Rd.
704        EmulateInstruction::Context context;
705        context.type = EmulateInstruction::eContextRegisterLoad;
706        Register dwarf_reg;
707        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
708        context.SetRegister (dwarf_reg);
709
710        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
711            return false;
712    }
713    return true;
714}
715
716// Move (immediate) writes an immediate value to the destination register.  It
717// can optionally update the condition flags based on the value.
718// MOV (immediate)
719bool
720EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
721{
722#if 0
723    // ARM pseudo code...
724    if (ConditionPassed())
725    {
726        EncodingSpecificOperations();
727        result = imm32;
728        if d == 15 then         // Can only occur for ARM encoding
729            ALUWritePC(result); // setflags is always FALSE here
730        else
731            R[d] = result;
732            if setflags then
733                APSR.N = result<31>;
734                APSR.Z = IsZeroBit(result);
735                APSR.C = carry;
736                // APSR.V unchanged
737    }
738#endif
739
740    if (ConditionPassed(opcode))
741    {
742        uint32_t Rd; // the destination register
743        uint32_t imm32; // the immediate value to be written to Rd
744        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
745        bool setflags;
746        switch (encoding) {
747            case eEncodingT1:
748                Rd = Bits32(opcode, 10, 8);
749                setflags = !InITBlock();
750                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
751                carry = APSR_C;
752
753                break;
754
755            case eEncodingT2:
756                Rd = Bits32(opcode, 11, 8);
757                setflags = BitIsSet(opcode, 20);
758                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
759                if (BadReg(Rd))
760                  return false;
761
762                break;
763
764            case eEncodingT3:
765            {
766                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
767                Rd = Bits32 (opcode, 11, 8);
768                setflags = false;
769                uint32_t imm4 = Bits32 (opcode, 19, 16);
770                uint32_t imm3 = Bits32 (opcode, 14, 12);
771                uint32_t i = Bit32 (opcode, 26);
772                uint32_t imm8 = Bits32 (opcode, 7, 0);
773                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
774
775                // if BadReg(d) then UNPREDICTABLE;
776                if (BadReg (Rd))
777                    return false;
778            }
779                break;
780
781            case eEncodingA1:
782                // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
783                Rd = Bits32 (opcode, 15, 12);
784                setflags = BitIsSet (opcode, 20);
785                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
786
787                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
788                if ((Rd == 15) && setflags)
789                    return EmulateSUBSPcLrEtc (opcode, encoding);
790
791                break;
792
793            case eEncodingA2:
794            {
795                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
796                Rd = Bits32 (opcode, 15, 12);
797                setflags = false;
798                uint32_t imm4 = Bits32 (opcode, 19, 16);
799                uint32_t imm12 = Bits32 (opcode, 11, 0);
800                imm32 = (imm4 << 12) | imm12;
801
802                // if d == 15 then UNPREDICTABLE;
803                if (Rd == 15)
804                    return false;
805            }
806                break;
807
808            default:
809                return false;
810        }
811        uint32_t result = imm32;
812
813        // The context specifies that an immediate is to be moved into Rd.
814        EmulateInstruction::Context context;
815        context.type = EmulateInstruction::eContextImmediate;
816        context.SetNoArgs ();
817
818        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
819            return false;
820    }
821    return true;
822}
823
824// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
825// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
826// unsigned values.
827//
828// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
829// limited to only a few forms of the instruction.
830bool
831EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
832{
833#if 0
834    if ConditionPassed() then
835        EncodingSpecificOperations();
836        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
837        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
838        result = operand1 * operand2;
839        R[d] = result<31:0>;
840        if setflags then
841            APSR.N = result<31>;
842            APSR.Z = IsZeroBit(result);
843            if ArchVersion() == 4 then
844                APSR.C = bit UNKNOWN;
845            // else APSR.C unchanged
846            // APSR.V always unchanged
847#endif
848
849    if (ConditionPassed(opcode))
850    {
851        uint32_t d;
852        uint32_t n;
853        uint32_t m;
854        bool setflags;
855
856        // EncodingSpecificOperations();
857        switch (encoding)
858        {
859            case eEncodingT1:
860                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
861                d = Bits32 (opcode, 2, 0);
862                n = Bits32 (opcode, 5, 3);
863                m = Bits32 (opcode, 2, 0);
864                setflags = !InITBlock();
865
866                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
867                if ((ArchVersion() < ARMv6) && (d == n))
868                    return false;
869
870                break;
871
872            case eEncodingT2:
873                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
874                d = Bits32 (opcode, 11, 8);
875                n = Bits32 (opcode, 19, 16);
876                m = Bits32 (opcode, 3, 0);
877                setflags = false;
878
879                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
880                if (BadReg (d) || BadReg (n) || BadReg (m))
881                    return false;
882
883                break;
884
885            case eEncodingA1:
886                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
887                d = Bits32 (opcode, 19, 16);
888                n = Bits32 (opcode, 3, 0);
889                m = Bits32 (opcode, 11, 8);
890                setflags = BitIsSet (opcode, 20);
891
892                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
893                if ((d == 15) ||  (n == 15) || (m == 15))
894                    return false;
895
896                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
897                if ((ArchVersion() < ARMv6) && (d == n))
898                    return false;
899
900                break;
901
902            default:
903                return false;
904        }
905
906        bool success = false;
907
908        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
909        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
910        if (!success)
911            return false;
912
913        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
914        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
915        if (!success)
916            return false;
917
918        // result = operand1 * operand2;
919        uint64_t result = operand1 * operand2;
920
921        // R[d] = result<31:0>;
922        Register op1_reg;
923        Register op2_reg;
924        op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
925        op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
926
927        EmulateInstruction::Context context;
928        context.type = eContextMultiplication;
929        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
930
931        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
932            return false;
933
934        // if setflags then
935        if (setflags)
936        {
937            // APSR.N = result<31>;
938            // APSR.Z = IsZeroBit(result);
939            m_new_inst_cpsr = m_opcode_cpsr;
940            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
941            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
942            if (m_new_inst_cpsr != m_opcode_cpsr)
943            {
944                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
945                    return false;
946            }
947
948            // if ArchVersion() == 4 then
949                // APSR.C = bit UNKNOWN;
950        }
951    }
952    return true;
953}
954
955// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
956// It can optionally update the condition flags based on the value.
957bool
958EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
959{
960#if 0
961    // ARM pseudo code...
962    if (ConditionPassed())
963    {
964        EncodingSpecificOperations();
965        result = NOT(imm32);
966        if d == 15 then         // Can only occur for ARM encoding
967            ALUWritePC(result); // setflags is always FALSE here
968        else
969            R[d] = result;
970            if setflags then
971                APSR.N = result<31>;
972                APSR.Z = IsZeroBit(result);
973                APSR.C = carry;
974                // APSR.V unchanged
975    }
976#endif
977
978    if (ConditionPassed(opcode))
979    {
980        uint32_t Rd; // the destination register
981        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
982        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
983        bool setflags;
984        switch (encoding) {
985        case eEncodingT1:
986            Rd = Bits32(opcode, 11, 8);
987            setflags = BitIsSet(opcode, 20);
988            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
989            break;
990        case eEncodingA1:
991            Rd = Bits32(opcode, 15, 12);
992            setflags = BitIsSet(opcode, 20);
993            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
994
995            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
996            if (Rd == 15 && setflags)
997                return EmulateSUBSPcLrEtc (opcode, encoding);
998            break;
999        default:
1000            return false;
1001        }
1002        uint32_t result = ~imm32;
1003
1004        // The context specifies that an immediate is to be moved into Rd.
1005        EmulateInstruction::Context context;
1006        context.type = EmulateInstruction::eContextImmediate;
1007        context.SetNoArgs ();
1008
1009        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1010            return false;
1011    }
1012    return true;
1013}
1014
1015// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1016// It can optionally update the condition flags based on the result.
1017bool
1018EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1019{
1020#if 0
1021    // ARM pseudo code...
1022    if (ConditionPassed())
1023    {
1024        EncodingSpecificOperations();
1025        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1026        result = NOT(shifted);
1027        if d == 15 then         // Can only occur for ARM encoding
1028            ALUWritePC(result); // setflags is always FALSE here
1029        else
1030            R[d] = result;
1031            if setflags then
1032                APSR.N = result<31>;
1033                APSR.Z = IsZeroBit(result);
1034                APSR.C = carry;
1035                // APSR.V unchanged
1036    }
1037#endif
1038
1039    if (ConditionPassed(opcode))
1040    {
1041        uint32_t Rm; // the source register
1042        uint32_t Rd; // the destination register
1043        ARM_ShifterType shift_t;
1044        uint32_t shift_n; // the shift applied to the value read from Rm
1045        bool setflags;
1046        uint32_t carry; // the carry bit after the shift operation
1047        switch (encoding) {
1048        case eEncodingT1:
1049            Rd = Bits32(opcode, 2, 0);
1050            Rm = Bits32(opcode, 5, 3);
1051            setflags = !InITBlock();
1052            shift_t = SRType_LSL;
1053            shift_n = 0;
1054            if (InITBlock())
1055                return false;
1056            break;
1057        case eEncodingT2:
1058            Rd = Bits32(opcode, 11, 8);
1059            Rm = Bits32(opcode, 3, 0);
1060            setflags = BitIsSet(opcode, 20);
1061            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1062            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1063            if (BadReg(Rd) || BadReg(Rm))
1064                return false;
1065            break;
1066        case eEncodingA1:
1067            Rd = Bits32(opcode, 15, 12);
1068            Rm = Bits32(opcode, 3, 0);
1069            setflags = BitIsSet(opcode, 20);
1070            shift_n = DecodeImmShiftARM(opcode, shift_t);
1071            break;
1072        default:
1073            return false;
1074        }
1075        bool success = false;
1076        uint32_t value = ReadCoreReg(Rm, &success);
1077        if (!success)
1078            return false;
1079
1080        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry);
1081        uint32_t result = ~shifted;
1082
1083        // The context specifies that an immediate is to be moved into Rd.
1084        EmulateInstruction::Context context;
1085        context.type = EmulateInstruction::eContextImmediate;
1086        context.SetNoArgs ();
1087
1088        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1089            return false;
1090    }
1091    return true;
1092}
1093
1094// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1095// LDR (literal)
1096bool
1097EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1098{
1099#if 0
1100    // ARM pseudo code...
1101    if (ConditionPassed())
1102    {
1103        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1104        base = Align(PC,4);
1105        address = if add then (base + imm32) else (base - imm32);
1106        data = MemU[address,4];
1107        if t == 15 then
1108            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1109        elsif UnalignedSupport() || address<1:0> = '00' then
1110            R[t] = data;
1111        else // Can only apply before ARMv7
1112            if CurrentInstrSet() == InstrSet_ARM then
1113                R[t] = ROR(data, 8*UInt(address<1:0>));
1114            else
1115                R[t] = bits(32) UNKNOWN;
1116    }
1117#endif
1118
1119    if (ConditionPassed(opcode))
1120    {
1121        bool success = false;
1122        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1123        if (!success)
1124            return false;
1125
1126        // PC relative immediate load context
1127        EmulateInstruction::Context context;
1128        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1129        Register pc_reg;
1130        pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1131        context.SetRegisterPlusOffset (pc_reg, 0);
1132
1133        uint32_t Rt;    // the destination register
1134        uint32_t imm32; // immediate offset from the PC
1135        bool add;       // +imm32 or -imm32?
1136        addr_t base;    // the base address
1137        addr_t address; // the PC relative address
1138        uint32_t data;  // the literal data value from the PC relative load
1139        switch (encoding) {
1140        case eEncodingT1:
1141            Rt = Bits32(opcode, 10, 8);
1142            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1143            add = true;
1144            break;
1145        case eEncodingT2:
1146            Rt = Bits32(opcode, 15, 12);
1147            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1148            add = BitIsSet(opcode, 23);
1149            if (Rt == 15 && InITBlock() && !LastInITBlock())
1150                return false;
1151            break;
1152        default:
1153            return false;
1154        }
1155
1156        base = Align(pc, 4);
1157        if (add)
1158            address = base + imm32;
1159        else
1160            address = base - imm32;
1161
1162        context.SetRegisterPlusOffset(pc_reg, address - base);
1163        data = MemURead(context, address, 4, 0, &success);
1164        if (!success)
1165            return false;
1166
1167        if (Rt == 15)
1168        {
1169            if (Bits32(address, 1, 0) == 0)
1170            {
1171                // In ARMv5T and above, this is an interworking branch.
1172                if (!LoadWritePC(context, data))
1173                    return false;
1174            }
1175            else
1176                return false;
1177        }
1178        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1179        {
1180            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1181                return false;
1182        }
1183        else // We don't handle ARM for now.
1184            return false;
1185
1186    }
1187    return true;
1188}
1189
1190// An add operation to adjust the SP.
1191// ADD (SP plus immediate)
1192bool
1193EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1194{
1195#if 0
1196    // ARM pseudo code...
1197    if (ConditionPassed())
1198    {
1199        EncodingSpecificOperations();
1200        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1201        if d == 15 then // Can only occur for ARM encoding
1202            ALUWritePC(result); // setflags is always FALSE here
1203        else
1204            R[d] = result;
1205            if setflags then
1206                APSR.N = result<31>;
1207                APSR.Z = IsZeroBit(result);
1208                APSR.C = carry;
1209                APSR.V = overflow;
1210    }
1211#endif
1212
1213    bool success = false;
1214
1215    if (ConditionPassed(opcode))
1216    {
1217        const addr_t sp = ReadCoreReg (SP_REG, &success);
1218        if (!success)
1219            return false;
1220        uint32_t imm32; // the immediate operand
1221        uint32_t d;
1222        bool setflags;
1223        switch (encoding)
1224        {
1225            case eEncodingT1:
1226                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1227                d = Bits32 (opcode, 10, 8);
1228                setflags = false;
1229                imm32 = (Bits32 (opcode, 7, 0) << 2);
1230
1231                break;
1232
1233            case eEncodingT2:
1234                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1235                d = 13;
1236                setflags = false;
1237                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1238
1239                break;
1240
1241            default:
1242                return false;
1243        }
1244        addr_t sp_offset = imm32;
1245        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1246
1247        EmulateInstruction::Context context;
1248        context.type = EmulateInstruction::eContextAdjustStackPointer;
1249        Register sp_reg;
1250        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1251        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1252
1253        if (d == 15)
1254        {
1255            if (!ALUWritePC (context, addr))
1256                return false;
1257        }
1258        else
1259        {
1260            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1261                return false;
1262        }
1263    }
1264    return true;
1265}
1266
1267// An add operation to adjust the SP.
1268// ADD (SP plus register)
1269bool
1270EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1271{
1272#if 0
1273    // ARM pseudo code...
1274    if (ConditionPassed())
1275    {
1276        EncodingSpecificOperations();
1277        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1278        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1279        if d == 15 then
1280            ALUWritePC(result); // setflags is always FALSE here
1281        else
1282            R[d] = result;
1283            if setflags then
1284                APSR.N = result<31>;
1285                APSR.Z = IsZeroBit(result);
1286                APSR.C = carry;
1287                APSR.V = overflow;
1288    }
1289#endif
1290
1291    bool success = false;
1292
1293    if (ConditionPassed(opcode))
1294    {
1295        const addr_t sp = ReadCoreReg (SP_REG, &success);
1296        if (!success)
1297            return false;
1298        uint32_t Rm; // the second operand
1299        switch (encoding) {
1300        case eEncodingT2:
1301            Rm = Bits32(opcode, 6, 3);
1302            break;
1303        default:
1304            return false;
1305        }
1306        int32_t reg_value = ReadCoreReg(Rm, &success);
1307        if (!success)
1308            return false;
1309
1310        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1311
1312        EmulateInstruction::Context context;
1313        context.type = EmulateInstruction::eContextAddition;
1314        Register sp_reg;
1315        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1316        Register other_reg;
1317        other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1318        context.SetRegisterRegisterOperands (sp_reg, other_reg);
1319
1320        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1321            return false;
1322    }
1323    return true;
1324}
1325
1326// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1327// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1328// from Thumb to ARM.
1329// BLX (immediate)
1330bool
1331EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1332{
1333#if 0
1334    // ARM pseudo code...
1335    if (ConditionPassed())
1336    {
1337        EncodingSpecificOperations();
1338        if CurrentInstrSet() == InstrSet_ARM then
1339            LR = PC - 4;
1340        else
1341            LR = PC<31:1> : '1';
1342        if targetInstrSet == InstrSet_ARM then
1343            targetAddress = Align(PC,4) + imm32;
1344        else
1345            targetAddress = PC + imm32;
1346        SelectInstrSet(targetInstrSet);
1347        BranchWritePC(targetAddress);
1348    }
1349#endif
1350
1351    bool success = true;
1352
1353    if (ConditionPassed(opcode))
1354    {
1355        EmulateInstruction::Context context;
1356        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1357        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1358        if (!success)
1359            return false;
1360        addr_t lr; // next instruction address
1361        addr_t target; // target address
1362        int32_t imm32; // PC-relative offset
1363        switch (encoding) {
1364        case eEncodingT1:
1365            {
1366            lr = pc | 1u; // return address
1367            uint32_t S = Bit32(opcode, 26);
1368            uint32_t imm10 = Bits32(opcode, 25, 16);
1369            uint32_t J1 = Bit32(opcode, 13);
1370            uint32_t J2 = Bit32(opcode, 11);
1371            uint32_t imm11 = Bits32(opcode, 10, 0);
1372            uint32_t I1 = !(J1 ^ S);
1373            uint32_t I2 = !(J2 ^ S);
1374            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1375            imm32 = llvm::SignExtend32<25>(imm25);
1376            target = pc + imm32;
1377            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1378            if (InITBlock() && !LastInITBlock())
1379                return false;
1380            break;
1381            }
1382        case eEncodingT2:
1383            {
1384            lr = pc | 1u; // return address
1385            uint32_t S = Bit32(opcode, 26);
1386            uint32_t imm10H = Bits32(opcode, 25, 16);
1387            uint32_t J1 = Bit32(opcode, 13);
1388            uint32_t J2 = Bit32(opcode, 11);
1389            uint32_t imm10L = Bits32(opcode, 10, 1);
1390            uint32_t I1 = !(J1 ^ S);
1391            uint32_t I2 = !(J2 ^ S);
1392            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1393            imm32 = llvm::SignExtend32<25>(imm25);
1394            target = Align(pc, 4) + imm32;
1395            context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1396            if (InITBlock() && !LastInITBlock())
1397                return false;
1398            break;
1399            }
1400        case eEncodingA1:
1401            lr = pc - 4; // return address
1402            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1403            target = Align(pc, 4) + imm32;
1404            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1405            break;
1406        case eEncodingA2:
1407            lr = pc - 4; // return address
1408            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1409            target = pc + imm32;
1410            context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
1411            break;
1412        default:
1413            return false;
1414        }
1415        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1416            return false;
1417        if (!BranchWritePC(context, target))
1418            return false;
1419    }
1420    return true;
1421}
1422
1423// Branch with Link and Exchange (register) calls a subroutine at an address and
1424// instruction set specified by a register.
1425// BLX (register)
1426bool
1427EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1428{
1429#if 0
1430    // ARM pseudo code...
1431    if (ConditionPassed())
1432    {
1433        EncodingSpecificOperations();
1434        target = R[m];
1435        if CurrentInstrSet() == InstrSet_ARM then
1436            next_instr_addr = PC - 4;
1437            LR = next_instr_addr;
1438        else
1439            next_instr_addr = PC - 2;
1440            LR = next_instr_addr<31:1> : '1';
1441        BXWritePC(target);
1442    }
1443#endif
1444
1445    bool success = false;
1446
1447    if (ConditionPassed(opcode))
1448    {
1449        EmulateInstruction::Context context;
1450        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1451        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1452        addr_t lr; // next instruction address
1453        if (!success)
1454            return false;
1455        uint32_t Rm; // the register with the target address
1456        switch (encoding) {
1457        case eEncodingT1:
1458            lr = (pc - 2) | 1u; // return address
1459            Rm = Bits32(opcode, 6, 3);
1460            // if m == 15 then UNPREDICTABLE;
1461            if (Rm == 15)
1462                return false;
1463            if (InITBlock() && !LastInITBlock())
1464                return false;
1465            break;
1466        case eEncodingA1:
1467            lr = pc - 4; // return address
1468            Rm = Bits32(opcode, 3, 0);
1469            // if m == 15 then UNPREDICTABLE;
1470            if (Rm == 15)
1471                return false;
1472            break;
1473        default:
1474            return false;
1475        }
1476        addr_t target = ReadCoreReg (Rm, &success);
1477        if (!success)
1478            return false;
1479        Register dwarf_reg;
1480        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1481        context.SetRegister (dwarf_reg);
1482        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1483            return false;
1484        if (!BXWritePC(context, target))
1485            return false;
1486    }
1487    return true;
1488}
1489
1490// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1491bool
1492EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1493{
1494#if 0
1495    // ARM pseudo code...
1496    if (ConditionPassed())
1497    {
1498        EncodingSpecificOperations();
1499        BXWritePC(R[m]);
1500    }
1501#endif
1502
1503    if (ConditionPassed(opcode))
1504    {
1505        EmulateInstruction::Context context;
1506        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1507        uint32_t Rm; // the register with the target address
1508        switch (encoding) {
1509        case eEncodingT1:
1510            Rm = Bits32(opcode, 6, 3);
1511            if (InITBlock() && !LastInITBlock())
1512                return false;
1513            break;
1514        case eEncodingA1:
1515            Rm = Bits32(opcode, 3, 0);
1516            break;
1517        default:
1518            return false;
1519        }
1520        bool success = false;
1521        addr_t target = ReadCoreReg (Rm, &success);
1522        if (!success)
1523            return false;
1524
1525        Register dwarf_reg;
1526        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1527        context.SetRegister (dwarf_reg);
1528        if (!BXWritePC(context, target))
1529            return false;
1530    }
1531    return true;
1532}
1533
1534// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1535// address and instruction set specified by a register as though it were a BX instruction.
1536//
1537// TODO: Emulate Jazelle architecture?
1538//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1539bool
1540EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1541{
1542#if 0
1543    // ARM pseudo code...
1544    if (ConditionPassed())
1545    {
1546        EncodingSpecificOperations();
1547        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1548            BXWritePC(R[m]);
1549        else
1550            if JazelleAcceptsExecution() then
1551                SwitchToJazelleExecution();
1552            else
1553                SUBARCHITECTURE_DEFINED handler call;
1554    }
1555#endif
1556
1557    if (ConditionPassed(opcode))
1558    {
1559        EmulateInstruction::Context context;
1560        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1561        uint32_t Rm; // the register with the target address
1562        switch (encoding) {
1563        case eEncodingT1:
1564            Rm = Bits32(opcode, 19, 16);
1565            if (BadReg(Rm))
1566                return false;
1567            if (InITBlock() && !LastInITBlock())
1568                return false;
1569            break;
1570        case eEncodingA1:
1571            Rm = Bits32(opcode, 3, 0);
1572            if (Rm == 15)
1573                return false;
1574            break;
1575        default:
1576            return false;
1577        }
1578        bool success = false;
1579        addr_t target = ReadCoreReg (Rm, &success);
1580        if (!success)
1581            return false;
1582
1583        Register dwarf_reg;
1584        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1585        context.SetRegister (dwarf_reg);
1586        if (!BXWritePC(context, target))
1587            return false;
1588    }
1589    return true;
1590}
1591
1592// Set r7 to point to some ip offset.
1593// SUB (immediate)
1594bool
1595EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1596{
1597#if 0
1598    // ARM pseudo code...
1599    if (ConditionPassed())
1600    {
1601        EncodingSpecificOperations();
1602        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1603        if d == 15 then // Can only occur for ARM encoding
1604           ALUWritePC(result); // setflags is always FALSE here
1605        else
1606            R[d] = result;
1607            if setflags then
1608                APSR.N = result<31>;
1609                APSR.Z = IsZeroBit(result);
1610                APSR.C = carry;
1611                APSR.V = overflow;
1612    }
1613#endif
1614
1615    if (ConditionPassed(opcode))
1616    {
1617        bool success = false;
1618        const addr_t ip = ReadCoreReg (12, &success);
1619        if (!success)
1620            return false;
1621        uint32_t imm32;
1622        switch (encoding) {
1623        case eEncodingA1:
1624            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1625            break;
1626        default:
1627            return false;
1628        }
1629        addr_t ip_offset = imm32;
1630        addr_t addr = ip - ip_offset; // the adjusted ip value
1631
1632        EmulateInstruction::Context context;
1633        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1634        Register dwarf_reg;
1635        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
1636        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1637
1638        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1639            return false;
1640    }
1641    return true;
1642}
1643
1644// Set ip to point to some stack offset.
1645// SUB (SP minus immediate)
1646bool
1647EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1648{
1649#if 0
1650    // ARM pseudo code...
1651    if (ConditionPassed())
1652    {
1653        EncodingSpecificOperations();
1654        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1655        if d == 15 then // Can only occur for ARM encoding
1656           ALUWritePC(result); // setflags is always FALSE here
1657        else
1658            R[d] = result;
1659            if setflags then
1660                APSR.N = result<31>;
1661                APSR.Z = IsZeroBit(result);
1662                APSR.C = carry;
1663                APSR.V = overflow;
1664    }
1665#endif
1666
1667    if (ConditionPassed(opcode))
1668    {
1669        bool success = false;
1670        const addr_t sp = ReadCoreReg (SP_REG, &success);
1671        if (!success)
1672            return false;
1673        uint32_t imm32;
1674        switch (encoding) {
1675        case eEncodingA1:
1676            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1677            break;
1678        default:
1679            return false;
1680        }
1681        addr_t sp_offset = imm32;
1682        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1683
1684        EmulateInstruction::Context context;
1685        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1686        Register dwarf_reg;
1687        dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1688        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1689
1690        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1691            return false;
1692    }
1693    return true;
1694}
1695
1696// This instruction subtracts an immediate value from the SP value, and writes
1697// the result to the destination register.
1698//
1699// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1700bool
1701EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1702{
1703#if 0
1704    // ARM pseudo code...
1705    if (ConditionPassed())
1706    {
1707        EncodingSpecificOperations();
1708        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1709        if d == 15 then        // Can only occur for ARM encoding
1710           ALUWritePC(result); // setflags is always FALSE here
1711        else
1712            R[d] = result;
1713            if setflags then
1714                APSR.N = result<31>;
1715                APSR.Z = IsZeroBit(result);
1716                APSR.C = carry;
1717                APSR.V = overflow;
1718    }
1719#endif
1720
1721    bool success = false;
1722    if (ConditionPassed(opcode))
1723    {
1724        const addr_t sp = ReadCoreReg (SP_REG, &success);
1725        if (!success)
1726            return false;
1727
1728        uint32_t Rd;
1729        bool setflags;
1730        uint32_t imm32;
1731        switch (encoding) {
1732        case eEncodingT1:
1733            Rd = 13;
1734            setflags = false;
1735            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1736            break;
1737        case eEncodingT2:
1738            Rd = Bits32(opcode, 11, 8);
1739            setflags = BitIsSet(opcode, 20);
1740            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1741            if (Rd == 15 && setflags)
1742                return EmulateCMPImm(opcode, eEncodingT2);
1743            if (Rd == 15 && !setflags)
1744                return false;
1745            break;
1746        case eEncodingT3:
1747            Rd = Bits32(opcode, 11, 8);
1748            setflags = false;
1749            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1750            if (Rd == 15)
1751                return false;
1752            break;
1753        case eEncodingA1:
1754            Rd = Bits32(opcode, 15, 12);
1755            setflags = BitIsSet(opcode, 20);
1756            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1757
1758            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1759            if (Rd == 15 && setflags)
1760                return EmulateSUBSPcLrEtc (opcode, encoding);
1761            break;
1762        default:
1763            return false;
1764        }
1765        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1766
1767        EmulateInstruction::Context context;
1768        if (Rd == 13)
1769        {
1770            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1771                                     // value gets passed down to context.SetImmediateSigned.
1772            context.type = EmulateInstruction::eContextAdjustStackPointer;
1773            context.SetImmediateSigned (-imm64); // the stack pointer offset
1774        }
1775        else
1776        {
1777            context.type = EmulateInstruction::eContextImmediate;
1778            context.SetNoArgs ();
1779        }
1780
1781        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1782            return false;
1783    }
1784    return true;
1785}
1786
1787// A store operation to the stack that also updates the SP.
1788bool
1789EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1790{
1791#if 0
1792    // ARM pseudo code...
1793    if (ConditionPassed())
1794    {
1795        EncodingSpecificOperations();
1796        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1797        address = if index then offset_addr else R[n];
1798        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1799        if wback then R[n] = offset_addr;
1800    }
1801#endif
1802
1803    bool success = false;
1804
1805    if (ConditionPassed(opcode))
1806    {
1807        const uint32_t addr_byte_size = GetAddressByteSize();
1808        const addr_t sp = ReadCoreReg (SP_REG, &success);
1809        if (!success)
1810            return false;
1811        uint32_t Rt; // the source register
1812        uint32_t imm12;
1813        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1814
1815        bool index;
1816        bool add;
1817        bool wback;
1818        switch (encoding) {
1819        case eEncodingA1:
1820            Rt = Bits32(opcode, 15, 12);
1821            imm12 = Bits32(opcode, 11, 0);
1822            Rn = Bits32 (opcode, 19, 16);
1823
1824            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1825                return false;
1826
1827            index = BitIsSet (opcode, 24);
1828            add = BitIsSet (opcode, 23);
1829            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1830
1831            if (wback && ((Rn == 15) || (Rn == Rt)))
1832                return false;
1833            break;
1834        default:
1835            return false;
1836        }
1837        addr_t offset_addr;
1838        if (add)
1839            offset_addr = sp + imm12;
1840        else
1841            offset_addr = sp - imm12;
1842
1843        addr_t addr;
1844        if (index)
1845            addr = offset_addr;
1846        else
1847            addr = sp;
1848
1849        EmulateInstruction::Context context;
1850        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1851        Register sp_reg;
1852        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1853        context.SetRegisterPlusOffset (sp_reg, addr - sp);
1854        if (Rt != 15)
1855        {
1856            uint32_t reg_value = ReadCoreReg(Rt, &success);
1857            if (!success)
1858                return false;
1859            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1860                return false;
1861        }
1862        else
1863        {
1864            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1865            if (!success)
1866                return false;
1867            if (!MemUWrite (context, addr, pc, addr_byte_size))
1868                return false;
1869        }
1870
1871
1872        if (wback)
1873        {
1874            context.type = EmulateInstruction::eContextAdjustStackPointer;
1875            context.SetImmediateSigned (addr - sp);
1876            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1877                return false;
1878        }
1879    }
1880    return true;
1881}
1882
1883// Vector Push stores multiple extension registers to the stack.
1884// It also updates SP to point to the start of the stored data.
1885bool
1886EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1887{
1888#if 0
1889    // ARM pseudo code...
1890    if (ConditionPassed())
1891    {
1892        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1893        address = SP - imm32;
1894        SP = SP - imm32;
1895        if single_regs then
1896            for r = 0 to regs-1
1897                MemA[address,4] = S[d+r]; address = address+4;
1898        else
1899            for r = 0 to regs-1
1900                // Store as two word-aligned words in the correct order for current endianness.
1901                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1902                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1903                address = address+8;
1904    }
1905#endif
1906
1907    bool success = false;
1908
1909    if (ConditionPassed(opcode))
1910    {
1911        const uint32_t addr_byte_size = GetAddressByteSize();
1912        const addr_t sp = ReadCoreReg (SP_REG, &success);
1913        if (!success)
1914            return false;
1915        bool single_regs;
1916        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1917        uint32_t imm32; // stack offset
1918        uint32_t regs;  // number of registers
1919        switch (encoding) {
1920        case eEncodingT1:
1921        case eEncodingA1:
1922            single_regs = false;
1923            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1924            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1925            // If UInt(imm8) is odd, see "FSTMX".
1926            regs = Bits32(opcode, 7, 0) / 2;
1927            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1928            if (regs == 0 || regs > 16 || (d + regs) > 32)
1929                return false;
1930            break;
1931        case eEncodingT2:
1932        case eEncodingA2:
1933            single_regs = true;
1934            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1935            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1936            regs = Bits32(opcode, 7, 0);
1937            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1938            if (regs == 0 || regs > 16 || (d + regs) > 32)
1939                return false;
1940            break;
1941        default:
1942            return false;
1943        }
1944        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1945        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1946        addr_t sp_offset = imm32;
1947        addr_t addr = sp - sp_offset;
1948        uint32_t i;
1949
1950        EmulateInstruction::Context context;
1951        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1952        Register dwarf_reg;
1953        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1954        Register sp_reg;
1955        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1956        for (i=0; i<regs; ++i)
1957        {
1958            dwarf_reg.num = start_reg + d + i;
1959            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1960            // uint64_t to accommodate 64-bit registers.
1961            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1962            if (!success)
1963                return false;
1964            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1965                return false;
1966            addr += reg_byte_size;
1967        }
1968
1969        context.type = EmulateInstruction::eContextAdjustStackPointer;
1970        context.SetImmediateSigned (-sp_offset);
1971
1972        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1973            return false;
1974    }
1975    return true;
1976}
1977
1978// Vector Pop loads multiple extension registers from the stack.
1979// It also updates SP to point just above the loaded data.
1980bool
1981EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
1982{
1983#if 0
1984    // ARM pseudo code...
1985    if (ConditionPassed())
1986    {
1987        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1988        address = SP;
1989        SP = SP + imm32;
1990        if single_regs then
1991            for r = 0 to regs-1
1992                S[d+r] = MemA[address,4]; address = address+4;
1993        else
1994            for r = 0 to regs-1
1995                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1996                // Combine the word-aligned words in the correct order for current endianness.
1997                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1998    }
1999#endif
2000
2001    bool success = false;
2002
2003    if (ConditionPassed(opcode))
2004    {
2005        const uint32_t addr_byte_size = GetAddressByteSize();
2006        const addr_t sp = ReadCoreReg (SP_REG, &success);
2007        if (!success)
2008            return false;
2009        bool single_regs;
2010        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2011        uint32_t imm32; // stack offset
2012        uint32_t regs;  // number of registers
2013        switch (encoding) {
2014        case eEncodingT1:
2015        case eEncodingA1:
2016            single_regs = false;
2017            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2018            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2019            // If UInt(imm8) is odd, see "FLDMX".
2020            regs = Bits32(opcode, 7, 0) / 2;
2021            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2022            if (regs == 0 || regs > 16 || (d + regs) > 32)
2023                return false;
2024            break;
2025        case eEncodingT2:
2026        case eEncodingA2:
2027            single_regs = true;
2028            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2029            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2030            regs = Bits32(opcode, 7, 0);
2031            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2032            if (regs == 0 || regs > 16 || (d + regs) > 32)
2033                return false;
2034            break;
2035        default:
2036            return false;
2037        }
2038        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2039        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2040        addr_t sp_offset = imm32;
2041        addr_t addr = sp;
2042        uint32_t i;
2043        uint64_t data; // uint64_t to accomodate 64-bit registers.
2044
2045        EmulateInstruction::Context context;
2046        context.type = EmulateInstruction::eContextPopRegisterOffStack;
2047        Register dwarf_reg;
2048        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
2049        Register sp_reg;
2050        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
2051        for (i=0; i<regs; ++i)
2052        {
2053            dwarf_reg.num = start_reg + d + i;
2054            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2055            data = MemARead(context, addr, reg_byte_size, 0, &success);
2056            if (!success)
2057                return false;
2058            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
2059                return false;
2060            addr += reg_byte_size;
2061        }
2062
2063        context.type = EmulateInstruction::eContextAdjustStackPointer;
2064        context.SetImmediateSigned (sp_offset);
2065
2066        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2067            return false;
2068    }
2069    return true;
2070}
2071
2072// SVC (previously SWI)
2073bool
2074EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2075{
2076#if 0
2077    // ARM pseudo code...
2078    if (ConditionPassed())
2079    {
2080        EncodingSpecificOperations();
2081        CallSupervisor();
2082    }
2083#endif
2084
2085    bool success = false;
2086
2087    if (ConditionPassed(opcode))
2088    {
2089        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2090        addr_t lr; // next instruction address
2091        if (!success)
2092            return false;
2093        uint32_t imm32; // the immediate constant
2094        uint32_t mode;  // ARM or Thumb mode
2095        switch (encoding) {
2096        case eEncodingT1:
2097            lr = (pc + 2) | 1u; // return address
2098            imm32 = Bits32(opcode, 7, 0);
2099            mode = eModeThumb;
2100            break;
2101        case eEncodingA1:
2102            lr = pc + 4; // return address
2103            imm32 = Bits32(opcode, 23, 0);
2104            mode = eModeARM;
2105            break;
2106        default:
2107            return false;
2108        }
2109
2110        EmulateInstruction::Context context;
2111        context.type = EmulateInstruction::eContextSupervisorCall;
2112        context.SetModeAndImmediate (mode, imm32);
2113        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2114            return false;
2115    }
2116    return true;
2117}
2118
2119// If Then makes up to four following instructions (the IT block) conditional.
2120bool
2121EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2122{
2123#if 0
2124    // ARM pseudo code...
2125    EncodingSpecificOperations();
2126    ITSTATE.IT<7:0> = firstcond:mask;
2127#endif
2128
2129    m_it_session.InitIT(Bits32(opcode, 7, 0));
2130    return true;
2131}
2132
2133// Branch causes a branch to a target address.
2134bool
2135EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2136{
2137#if 0
2138    // ARM pseudo code...
2139    if (ConditionPassed())
2140    {
2141        EncodingSpecificOperations();
2142        BranchWritePC(PC + imm32);
2143    }
2144#endif
2145
2146    bool success = false;
2147
2148    if (ConditionPassed(opcode))
2149    {
2150        EmulateInstruction::Context context;
2151        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2152        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2153        if (!success)
2154            return false;
2155        addr_t target; // target address
2156        int32_t imm32; // PC-relative offset
2157        switch (encoding) {
2158        case eEncodingT1:
2159            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2160            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2161            target = pc + imm32;
2162            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2163            break;
2164        case eEncodingT2:
2165            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2166            target = pc + imm32;
2167            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2168            break;
2169        case eEncodingT3:
2170            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2171            {
2172            uint32_t S = Bit32(opcode, 26);
2173            uint32_t imm6 = Bits32(opcode, 21, 16);
2174            uint32_t J1 = Bit32(opcode, 13);
2175            uint32_t J2 = Bit32(opcode, 11);
2176            uint32_t imm11 = Bits32(opcode, 10, 0);
2177            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2178            imm32 = llvm::SignExtend32<21>(imm21);
2179            target = pc + imm32;
2180            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2181            break;
2182            }
2183        case eEncodingT4:
2184            {
2185            uint32_t S = Bit32(opcode, 26);
2186            uint32_t imm10 = Bits32(opcode, 25, 16);
2187            uint32_t J1 = Bit32(opcode, 13);
2188            uint32_t J2 = Bit32(opcode, 11);
2189            uint32_t imm11 = Bits32(opcode, 10, 0);
2190            uint32_t I1 = !(J1 ^ S);
2191            uint32_t I2 = !(J2 ^ S);
2192            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2193            imm32 = llvm::SignExtend32<25>(imm25);
2194            target = pc + imm32;
2195            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2196            break;
2197            }
2198        case eEncodingA1:
2199            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2200            target = pc + imm32;
2201            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
2202            break;
2203        default:
2204            return false;
2205        }
2206        if (!BranchWritePC(context, target))
2207            return false;
2208    }
2209    return true;
2210}
2211
2212// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2213// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2214// CBNZ, CBZ
2215bool
2216EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2217{
2218#if 0
2219    // ARM pseudo code...
2220    EncodingSpecificOperations();
2221    if nonzero ^ IsZero(R[n]) then
2222        BranchWritePC(PC + imm32);
2223#endif
2224
2225    bool success = false;
2226
2227    // Read the register value from the operand register Rn.
2228    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2229    if (!success)
2230        return false;
2231
2232    EmulateInstruction::Context context;
2233    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2234    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2235    if (!success)
2236        return false;
2237
2238    addr_t target;  // target address
2239    uint32_t imm32; // PC-relative offset to branch forward
2240    bool nonzero;
2241    switch (encoding) {
2242    case eEncodingT1:
2243        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2244        nonzero = BitIsSet(opcode, 11);
2245        target = pc + imm32;
2246        context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2247        break;
2248    default:
2249        return false;
2250    }
2251    if (nonzero ^ (reg_val == 0))
2252        if (!BranchWritePC(context, target))
2253            return false;
2254
2255    return true;
2256}
2257
2258// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2259// A base register provides a pointer to the table, and a second register supplies an index into the table.
2260// The branch length is twice the value of the byte returned from the table.
2261//
2262// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2263// A base register provides a pointer to the table, and a second register supplies an index into the table.
2264// The branch length is twice the value of the halfword returned from the table.
2265// TBB, TBH
2266bool
2267EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2268{
2269#if 0
2270    // ARM pseudo code...
2271    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2272    if is_tbh then
2273        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2274    else
2275        halfwords = UInt(MemU[R[n]+R[m], 1]);
2276    BranchWritePC(PC + 2*halfwords);
2277#endif
2278
2279    bool success = false;
2280
2281    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2282    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2283    bool is_tbh;     // true if table branch halfword
2284    switch (encoding) {
2285    case eEncodingT1:
2286        Rn = Bits32(opcode, 19, 16);
2287        Rm = Bits32(opcode, 3, 0);
2288        is_tbh = BitIsSet(opcode, 4);
2289        if (Rn == 13 || BadReg(Rm))
2290            return false;
2291        if (InITBlock() && !LastInITBlock())
2292            return false;
2293        break;
2294    default:
2295        return false;
2296    }
2297
2298    // Read the address of the table from the operand register Rn.
2299    // The PC can be used, in which case the table immediately follows this instruction.
2300    uint32_t base = ReadCoreReg(Rm, &success);
2301    if (!success)
2302        return false;
2303
2304    // the table index
2305    uint32_t index = ReadCoreReg(Rm, &success);
2306    if (!success)
2307        return false;
2308
2309    // the offsetted table address
2310    addr_t addr = base + (is_tbh ? index*2 : index);
2311
2312    // PC-relative offset to branch forward
2313    EmulateInstruction::Context context;
2314    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2315    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2316    if (!success)
2317        return false;
2318
2319    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2320    if (!success)
2321        return false;
2322
2323    // target address
2324    addr_t target = pc + offset;
2325    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2326    context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
2327
2328    if (!BranchWritePC(context, target))
2329        return false;
2330
2331    return true;
2332}
2333
2334// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2335// It can optionally update the condition flags based on the result.
2336bool
2337EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2338{
2339#if 0
2340    if ConditionPassed() then
2341        EncodingSpecificOperations();
2342        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2343        R[d] = result;
2344        if setflags then
2345            APSR.N = result<31>;
2346            APSR.Z = IsZeroBit(result);
2347            APSR.C = carry;
2348            APSR.V = overflow;
2349#endif
2350
2351    bool success = false;
2352
2353    if (ConditionPassed(opcode))
2354    {
2355        uint32_t d;
2356        uint32_t n;
2357        bool setflags;
2358        uint32_t imm32;
2359        uint32_t carry_out;
2360
2361        //EncodingSpecificOperations();
2362        switch (encoding)
2363        {
2364            case eEncodingT1:
2365                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2366                d = Bits32 (opcode, 2, 0);
2367                n = Bits32 (opcode, 5, 3);
2368                setflags = !InITBlock();
2369                imm32 = Bits32 (opcode, 8,6);
2370
2371                break;
2372
2373            case eEncodingT2:
2374                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2375                d = Bits32 (opcode, 10, 8);
2376                n = Bits32 (opcode, 10, 8);
2377                setflags = !InITBlock();
2378                imm32 = Bits32 (opcode, 7, 0);
2379
2380                break;
2381
2382            case eEncodingT3:
2383                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2384                // if Rn == '1101' then SEE ADD (SP plus immediate);
2385                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2386                d = Bits32 (opcode, 11, 8);
2387                n = Bits32 (opcode, 19, 16);
2388                setflags = BitIsSet (opcode, 20);
2389                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2390
2391                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2392                if (BadReg (d) || (n == 15))
2393                    return false;
2394
2395                break;
2396
2397            case eEncodingT4:
2398            {
2399                // if Rn == '1111' then SEE ADR;
2400                // if Rn == '1101' then SEE ADD (SP plus immediate);
2401                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2402                d = Bits32 (opcode, 11, 8);
2403                n = Bits32 (opcode, 19, 16);
2404                setflags = false;
2405                uint32_t i = Bit32 (opcode, 26);
2406                uint32_t imm3 = Bits32 (opcode, 14, 12);
2407                uint32_t imm8 = Bits32 (opcode, 7, 0);
2408                imm32 = (i << 11) | (imm3 << 8) | imm8;
2409
2410                // if BadReg(d) then UNPREDICTABLE;
2411                if (BadReg (d))
2412                    return false;
2413
2414                break;
2415            }
2416            default:
2417                return false;
2418        }
2419
2420        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2421        if (!success)
2422            return false;
2423
2424        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2425        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2426
2427        Register reg_n;
2428        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2429
2430        EmulateInstruction::Context context;
2431        context.type = eContextAddition;
2432        context.SetRegisterPlusOffset (reg_n, imm32);
2433
2434        //R[d] = result;
2435        //if setflags then
2436            //APSR.N = result<31>;
2437            //APSR.Z = IsZeroBit(result);
2438            //APSR.C = carry;
2439            //APSR.V = overflow;
2440        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2441            return false;
2442
2443    }
2444    return true;
2445}
2446
2447// This instruction adds an immediate value to a register value, and writes the result to the destination
2448// register.  It can optionally update the condition flags based on the result.
2449bool
2450EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2451{
2452#if 0
2453    // ARM pseudo code...
2454    if ConditionPassed() then
2455        EncodingSpecificOperations();
2456        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2457        if d == 15 then
2458            ALUWritePC(result); // setflags is always FALSE here
2459        else
2460            R[d] = result;
2461            if setflags then
2462                APSR.N = result<31>;
2463                APSR.Z = IsZeroBit(result);
2464                APSR.C = carry;
2465                APSR.V = overflow;
2466#endif
2467
2468    bool success = false;
2469
2470    if (ConditionPassed(opcode))
2471    {
2472        uint32_t Rd, Rn;
2473        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2474        bool setflags;
2475        switch (encoding)
2476        {
2477        case eEncodingA1:
2478            Rd = Bits32(opcode, 15, 12);
2479            Rn = Bits32(opcode, 19, 16);
2480            setflags = BitIsSet(opcode, 20);
2481            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2482            break;
2483        default:
2484            return false;
2485        }
2486
2487        // Read the first operand.
2488        uint32_t val1 = ReadCoreReg(Rn, &success);
2489        if (!success)
2490            return false;
2491
2492        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2493
2494        EmulateInstruction::Context context;
2495        context.type = EmulateInstruction::eContextAddition;
2496        Register dwarf_reg;
2497        dwarf_reg.SetRegister (eRegisterKindDWARF, Rn);
2498        context.SetRegisterPlusOffset (dwarf_reg, imm32);
2499
2500        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2501            return false;
2502    }
2503    return true;
2504}
2505
2506// This instruction adds a register value and an optionally-shifted register value, and writes the result
2507// to the destination register. It can optionally update the condition flags based on the result.
2508bool
2509EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2510{
2511#if 0
2512    // ARM pseudo code...
2513    if ConditionPassed() then
2514        EncodingSpecificOperations();
2515        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2516        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2517        if d == 15 then
2518            ALUWritePC(result); // setflags is always FALSE here
2519        else
2520            R[d] = result;
2521            if setflags then
2522                APSR.N = result<31>;
2523                APSR.Z = IsZeroBit(result);
2524                APSR.C = carry;
2525                APSR.V = overflow;
2526#endif
2527
2528    bool success = false;
2529
2530    if (ConditionPassed(opcode))
2531    {
2532        uint32_t Rd, Rn, Rm;
2533        ARM_ShifterType shift_t;
2534        uint32_t shift_n; // the shift applied to the value read from Rm
2535        bool setflags;
2536        switch (encoding)
2537        {
2538        case eEncodingT1:
2539            Rd = Bits32(opcode, 2, 0);
2540            Rn = Bits32(opcode, 5, 3);
2541            Rm = Bits32(opcode, 8, 6);
2542            setflags = !InITBlock();
2543            shift_t = SRType_LSL;
2544            shift_n = 0;
2545            break;
2546        case eEncodingT2:
2547            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2548            Rm = Bits32(opcode, 6, 3);
2549            setflags = false;
2550            shift_t = SRType_LSL;
2551            shift_n = 0;
2552            if (Rn == 15 && Rm == 15)
2553                return false;
2554            if (Rd == 15 && InITBlock() && !LastInITBlock())
2555                return false;
2556            break;
2557        case eEncodingA1:
2558            Rd = Bits32(opcode, 15, 12);
2559            Rn = Bits32(opcode, 19, 16);
2560            Rm = Bits32(opcode, 3, 0);
2561            setflags = BitIsSet(opcode, 20);
2562            shift_n = DecodeImmShiftARM(opcode, shift_t);
2563            break;
2564        default:
2565            return false;
2566        }
2567
2568        // Read the first operand.
2569        uint32_t val1 = ReadCoreReg(Rn, &success);
2570        if (!success)
2571            return false;
2572
2573        // Read the second operand.
2574        uint32_t val2 = ReadCoreReg(Rm, &success);
2575        if (!success)
2576            return false;
2577
2578        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2579        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2580
2581        EmulateInstruction::Context context;
2582        context.type = EmulateInstruction::eContextAddition;
2583        Register op1_reg;
2584        Register op2_reg;
2585        op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
2586        op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
2587        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2588
2589        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2590            return false;
2591    }
2592    return true;
2593}
2594
2595// Compare Negative (immediate) adds a register value and an immediate value.
2596// It updates the condition flags based on the result, and discards the result.
2597bool
2598EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2599{
2600#if 0
2601    // ARM pseudo code...
2602    if ConditionPassed() then
2603        EncodingSpecificOperations();
2604        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2605        APSR.N = result<31>;
2606        APSR.Z = IsZeroBit(result);
2607        APSR.C = carry;
2608        APSR.V = overflow;
2609#endif
2610
2611    bool success = false;
2612
2613    uint32_t Rn; // the first operand
2614    uint32_t imm32; // the immediate value to be compared with
2615    switch (encoding) {
2616    case eEncodingT1:
2617        Rn = Bits32(opcode, 19, 16);
2618        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2619        if (Rn == 15)
2620            return false;
2621        break;
2622    case eEncodingA1:
2623        Rn = Bits32(opcode, 19, 16);
2624        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2625        break;
2626    default:
2627        return false;
2628    }
2629    // Read the register value from the operand register Rn.
2630    uint32_t reg_val = ReadCoreReg(Rn, &success);
2631    if (!success)
2632        return false;
2633
2634    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2635
2636    EmulateInstruction::Context context;
2637    context.type = EmulateInstruction::eContextImmediate;
2638    context.SetNoArgs ();
2639    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2640        return false;
2641
2642    return true;
2643}
2644
2645// Compare Negative (register) adds a register value and an optionally-shifted register value.
2646// It updates the condition flags based on the result, and discards the result.
2647bool
2648EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2649{
2650#if 0
2651    // ARM pseudo code...
2652    if ConditionPassed() then
2653        EncodingSpecificOperations();
2654        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2655        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2656        APSR.N = result<31>;
2657        APSR.Z = IsZeroBit(result);
2658        APSR.C = carry;
2659        APSR.V = overflow;
2660#endif
2661
2662    bool success = false;
2663
2664    uint32_t Rn; // the first operand
2665    uint32_t Rm; // the second operand
2666    ARM_ShifterType shift_t;
2667    uint32_t shift_n; // the shift applied to the value read from Rm
2668    switch (encoding) {
2669    case eEncodingT1:
2670        Rn = Bits32(opcode, 2, 0);
2671        Rm = Bits32(opcode, 5, 3);
2672        shift_t = SRType_LSL;
2673        shift_n = 0;
2674        break;
2675    case eEncodingT2:
2676        Rn = Bits32(opcode, 19, 16);
2677        Rm = Bits32(opcode, 3, 0);
2678        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2679        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2680        if (Rn == 15 || BadReg(Rm))
2681            return false;
2682        break;
2683    case eEncodingA1:
2684        Rn = Bits32(opcode, 19, 16);
2685        Rm = Bits32(opcode, 3, 0);
2686        shift_n = DecodeImmShiftARM(opcode, shift_t);
2687        break;
2688    default:
2689        return false;
2690    }
2691    // Read the register value from register Rn.
2692    uint32_t val1 = ReadCoreReg(Rn, &success);
2693    if (!success)
2694        return false;
2695
2696    // Read the register value from register Rm.
2697    uint32_t val2 = ReadCoreReg(Rm, &success);
2698    if (!success)
2699        return false;
2700
2701    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2702    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2703
2704    EmulateInstruction::Context context;
2705    context.type = EmulateInstruction::eContextImmediate;
2706    context.SetNoArgs();
2707    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2708        return false;
2709
2710    return true;
2711}
2712
2713// Compare (immediate) subtracts an immediate value from a register value.
2714// It updates the condition flags based on the result, and discards the result.
2715bool
2716EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2717{
2718#if 0
2719    // ARM pseudo code...
2720    if ConditionPassed() then
2721        EncodingSpecificOperations();
2722        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2723        APSR.N = result<31>;
2724        APSR.Z = IsZeroBit(result);
2725        APSR.C = carry;
2726        APSR.V = overflow;
2727#endif
2728
2729    bool success = false;
2730
2731    uint32_t Rn; // the first operand
2732    uint32_t imm32; // the immediate value to be compared with
2733    switch (encoding) {
2734    case eEncodingT1:
2735        Rn = Bits32(opcode, 10, 8);
2736        imm32 = Bits32(opcode, 7, 0);
2737        break;
2738    case eEncodingT2:
2739        Rn = Bits32(opcode, 19, 16);
2740        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2741        if (Rn == 15)
2742            return false;
2743        break;
2744    case eEncodingA1:
2745        Rn = Bits32(opcode, 19, 16);
2746        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2747        break;
2748    default:
2749        return false;
2750    }
2751    // Read the register value from the operand register Rn.
2752    uint32_t reg_val = ReadCoreReg(Rn, &success);
2753    if (!success)
2754        return false;
2755
2756    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2757
2758    EmulateInstruction::Context context;
2759    context.type = EmulateInstruction::eContextImmediate;
2760    context.SetNoArgs ();
2761    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2762        return false;
2763
2764    return true;
2765}
2766
2767// Compare (register) subtracts an optionally-shifted register value from a register value.
2768// It updates the condition flags based on the result, and discards the result.
2769bool
2770EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2771{
2772#if 0
2773    // ARM pseudo code...
2774    if ConditionPassed() then
2775        EncodingSpecificOperations();
2776        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2777        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2778        APSR.N = result<31>;
2779        APSR.Z = IsZeroBit(result);
2780        APSR.C = carry;
2781        APSR.V = overflow;
2782#endif
2783
2784    bool success = false;
2785
2786    uint32_t Rn; // the first operand
2787    uint32_t Rm; // the second operand
2788    ARM_ShifterType shift_t;
2789    uint32_t shift_n; // the shift applied to the value read from Rm
2790    switch (encoding) {
2791    case eEncodingT1:
2792        Rn = Bits32(opcode, 2, 0);
2793        Rm = Bits32(opcode, 5, 3);
2794        shift_t = SRType_LSL;
2795        shift_n = 0;
2796        break;
2797    case eEncodingT2:
2798        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2799        Rm = Bits32(opcode, 6, 3);
2800        shift_t = SRType_LSL;
2801        shift_n = 0;
2802        if (Rn < 8 && Rm < 8)
2803            return false;
2804        if (Rn == 15 || Rm == 15)
2805            return false;
2806        break;
2807    case eEncodingA1:
2808        Rn = Bits32(opcode, 19, 16);
2809        Rm = Bits32(opcode, 3, 0);
2810        shift_n = DecodeImmShiftARM(opcode, shift_t);
2811        break;
2812    default:
2813        return false;
2814    }
2815    // Read the register value from register Rn.
2816    uint32_t val1 = ReadCoreReg(Rn, &success);
2817    if (!success)
2818        return false;
2819
2820    // Read the register value from register Rm.
2821    uint32_t val2 = ReadCoreReg(Rm, &success);
2822    if (!success)
2823        return false;
2824
2825    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2826    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2827
2828    EmulateInstruction::Context context;
2829    context.type = EmulateInstruction::eContextImmediate;
2830    context.SetNoArgs();
2831    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2832        return false;
2833
2834    return true;
2835}
2836
2837// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2838// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2839// optionally update the condition flags based on the result.
2840bool
2841EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2842{
2843#if 0
2844    // ARM pseudo code...
2845    if ConditionPassed() then
2846        EncodingSpecificOperations();
2847        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2848        if d == 15 then         // Can only occur for ARM encoding
2849            ALUWritePC(result); // setflags is always FALSE here
2850        else
2851            R[d] = result;
2852            if setflags then
2853                APSR.N = result<31>;
2854                APSR.Z = IsZeroBit(result);
2855                APSR.C = carry;
2856                // APSR.V unchanged
2857#endif
2858
2859    return EmulateShiftImm (opcode, encoding, SRType_ASR);
2860}
2861
2862// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2863// shifting in copies of its sign bit, and writes the result to the destination register.
2864// The variable number of bits is read from the bottom byte of a register. It can optionally update
2865// the condition flags based on the result.
2866bool
2867EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2868{
2869#if 0
2870    // ARM pseudo code...
2871    if ConditionPassed() then
2872        EncodingSpecificOperations();
2873        shift_n = UInt(R[m]<7:0>);
2874        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2875        R[d] = result;
2876        if setflags then
2877            APSR.N = result<31>;
2878            APSR.Z = IsZeroBit(result);
2879            APSR.C = carry;
2880            // APSR.V unchanged
2881#endif
2882
2883    return EmulateShiftReg (opcode, encoding, SRType_ASR);
2884}
2885
2886// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2887// shifting in zeros, and writes the result to the destination register.  It can optionally
2888// update the condition flags based on the result.
2889bool
2890EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2891{
2892#if 0
2893    // ARM pseudo code...
2894    if ConditionPassed() then
2895        EncodingSpecificOperations();
2896        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2897        if d == 15 then         // Can only occur for ARM encoding
2898            ALUWritePC(result); // setflags is always FALSE here
2899        else
2900            R[d] = result;
2901            if setflags then
2902                APSR.N = result<31>;
2903                APSR.Z = IsZeroBit(result);
2904                APSR.C = carry;
2905                // APSR.V unchanged
2906#endif
2907
2908    return EmulateShiftImm (opcode, encoding, SRType_LSL);
2909}
2910
2911// Logical Shift Left (register) shifts a register value left by a variable number of bits,
2912// shifting in zeros, and writes the result to the destination register.  The variable number
2913// of bits is read from the bottom byte of a register. It can optionally update the condition
2914// flags based on the result.
2915bool
2916EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
2917{
2918#if 0
2919    // ARM pseudo code...
2920    if ConditionPassed() then
2921        EncodingSpecificOperations();
2922        shift_n = UInt(R[m]<7:0>);
2923        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2924        R[d] = result;
2925        if setflags then
2926            APSR.N = result<31>;
2927            APSR.Z = IsZeroBit(result);
2928            APSR.C = carry;
2929            // APSR.V unchanged
2930#endif
2931
2932    return EmulateShiftReg (opcode, encoding, SRType_LSL);
2933}
2934
2935// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
2936// shifting in zeros, and writes the result to the destination register.  It can optionally
2937// update the condition flags based on the result.
2938bool
2939EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
2940{
2941#if 0
2942    // ARM pseudo code...
2943    if ConditionPassed() then
2944        EncodingSpecificOperations();
2945        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2946        if d == 15 then         // Can only occur for ARM encoding
2947            ALUWritePC(result); // setflags is always FALSE here
2948        else
2949            R[d] = result;
2950            if setflags then
2951                APSR.N = result<31>;
2952                APSR.Z = IsZeroBit(result);
2953                APSR.C = carry;
2954                // APSR.V unchanged
2955#endif
2956
2957    return EmulateShiftImm (opcode, encoding, SRType_LSR);
2958}
2959
2960// Logical Shift Right (register) shifts a register value right by a variable number of bits,
2961// shifting in zeros, and writes the result to the destination register.  The variable number
2962// of bits is read from the bottom byte of a register. It can optionally update the condition
2963// flags based on the result.
2964bool
2965EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
2966{
2967#if 0
2968    // ARM pseudo code...
2969    if ConditionPassed() then
2970        EncodingSpecificOperations();
2971        shift_n = UInt(R[m]<7:0>);
2972        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2973        R[d] = result;
2974        if setflags then
2975            APSR.N = result<31>;
2976            APSR.Z = IsZeroBit(result);
2977            APSR.C = carry;
2978            // APSR.V unchanged
2979#endif
2980
2981    return EmulateShiftReg (opcode, encoding, SRType_LSR);
2982}
2983
2984// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2985// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2986// It can optionally update the condition flags based on the result.
2987bool
2988EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
2989{
2990#if 0
2991    // ARM pseudo code...
2992    if ConditionPassed() then
2993        EncodingSpecificOperations();
2994        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2995        if d == 15 then         // Can only occur for ARM encoding
2996            ALUWritePC(result); // setflags is always FALSE here
2997        else
2998            R[d] = result;
2999            if setflags then
3000                APSR.N = result<31>;
3001                APSR.Z = IsZeroBit(result);
3002                APSR.C = carry;
3003                // APSR.V unchanged
3004#endif
3005
3006    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3007}
3008
3009// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3010// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3011// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3012// flags based on the result.
3013bool
3014EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3015{
3016#if 0
3017    // ARM pseudo code...
3018    if ConditionPassed() then
3019        EncodingSpecificOperations();
3020        shift_n = UInt(R[m]<7:0>);
3021        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3022        R[d] = result;
3023        if setflags then
3024            APSR.N = result<31>;
3025            APSR.Z = IsZeroBit(result);
3026            APSR.C = carry;
3027            // APSR.V unchanged
3028#endif
3029
3030    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3031}
3032
3033// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3034// with the carry flag shifted into bit [31].
3035//
3036// RRX can optionally update the condition flags based on the result.
3037// In that case, bit [0] is shifted into the carry flag.
3038bool
3039EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3040{
3041#if 0
3042    // ARM pseudo code...
3043    if ConditionPassed() then
3044        EncodingSpecificOperations();
3045        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3046        if d == 15 then         // Can only occur for ARM encoding
3047            ALUWritePC(result); // setflags is always FALSE here
3048        else
3049            R[d] = result;
3050            if setflags then
3051                APSR.N = result<31>;
3052                APSR.Z = IsZeroBit(result);
3053                APSR.C = carry;
3054                // APSR.V unchanged
3055#endif
3056
3057    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3058}
3059
3060bool
3061EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3062{
3063    assert(shift_type == SRType_ASR
3064           || shift_type == SRType_LSL
3065           || shift_type == SRType_LSR
3066           || shift_type == SRType_ROR
3067           || shift_type == SRType_RRX);
3068
3069    bool success = false;
3070
3071    if (ConditionPassed(opcode))
3072    {
3073        uint32_t Rd;    // the destination register
3074        uint32_t Rm;    // the first operand register
3075        uint32_t imm5;  // encoding for the shift amount
3076        uint32_t carry; // the carry bit after the shift operation
3077        bool setflags;
3078
3079        // Special case handling!
3080        // A8.6.139 ROR (immediate) -- Encoding T1
3081        ARMEncoding use_encoding = encoding;
3082        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3083        {
3084            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3085            // have the same decoding of bit fields as the other Thumb2 shift operations.
3086            use_encoding = eEncodingT2;
3087        }
3088
3089        switch (use_encoding) {
3090        case eEncodingT1:
3091            // Due to the above special case handling!
3092            assert(shift_type != SRType_ROR);
3093
3094            Rd = Bits32(opcode, 2, 0);
3095            Rm = Bits32(opcode, 5, 3);
3096            setflags = !InITBlock();
3097            imm5 = Bits32(opcode, 10, 6);
3098            break;
3099        case eEncodingT2:
3100            // A8.6.141 RRX
3101            assert(shift_type != SRType_RRX);
3102
3103            Rd = Bits32(opcode, 11, 8);
3104            Rm = Bits32(opcode, 3, 0);
3105            setflags = BitIsSet(opcode, 20);
3106            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3107            if (BadReg(Rd) || BadReg(Rm))
3108                return false;
3109            break;
3110        case eEncodingA1:
3111            Rd = Bits32(opcode, 15, 12);
3112            Rm = Bits32(opcode, 3, 0);
3113            setflags = BitIsSet(opcode, 20);
3114            imm5 = Bits32(opcode, 11, 7);
3115            break;
3116        default:
3117            return false;
3118        }
3119
3120        // A8.6.139 ROR (immediate)
3121        if (shift_type == SRType_ROR && imm5 == 0)
3122            shift_type = SRType_RRX;
3123
3124        // Get the first operand.
3125        uint32_t value = ReadCoreReg (Rm, &success);
3126        if (!success)
3127            return false;
3128
3129        // Decode the shift amount if not RRX.
3130        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3131
3132        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3133
3134        // The context specifies that an immediate is to be moved into Rd.
3135        EmulateInstruction::Context context;
3136        context.type = EmulateInstruction::eContextImmediate;
3137        context.SetNoArgs ();
3138
3139        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3140            return false;
3141    }
3142    return true;
3143}
3144
3145bool
3146EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3147{
3148    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
3149
3150    bool success = false;
3151
3152    if (ConditionPassed(opcode))
3153    {
3154        uint32_t Rd;    // the destination register
3155        uint32_t Rn;    // the first operand register
3156        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3157        uint32_t carry; // the carry bit after the shift operation
3158        bool setflags;
3159        switch (encoding) {
3160        case eEncodingT1:
3161            Rd = Bits32(opcode, 2, 0);
3162            Rn = Rd;
3163            Rm = Bits32(opcode, 5, 3);
3164            setflags = !InITBlock();
3165            break;
3166        case eEncodingT2:
3167            Rd = Bits32(opcode, 11, 8);
3168            Rn = Bits32(opcode, 19, 16);
3169            Rm = Bits32(opcode, 3, 0);
3170            setflags = BitIsSet(opcode, 20);
3171            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3172                return false;
3173            break;
3174        case eEncodingA1:
3175            Rd = Bits32(opcode, 15, 12);
3176            Rn = Bits32(opcode, 3, 0);
3177            Rm = Bits32(opcode, 11, 8);
3178            setflags = BitIsSet(opcode, 20);
3179            if (Rd == 15 || Rn == 15 || Rm == 15)
3180                return false;
3181            break;
3182        default:
3183            return false;
3184        }
3185
3186        // Get the first operand.
3187        uint32_t value = ReadCoreReg (Rn, &success);
3188        if (!success)
3189            return false;
3190        // Get the Rm register content.
3191        uint32_t val = ReadCoreReg (Rm, &success);
3192        if (!success)
3193            return false;
3194
3195        // Get the shift amount.
3196        uint32_t amt = Bits32(val, 7, 0);
3197
3198        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3199
3200        // The context specifies that an immediate is to be moved into Rd.
3201        EmulateInstruction::Context context;
3202        context.type = EmulateInstruction::eContextImmediate;
3203        context.SetNoArgs ();
3204
3205        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3206            return false;
3207    }
3208    return true;
3209}
3210
3211// LDM loads multiple registers from consecutive memory locations, using an
3212// address from a base register.  Optionally the address just above the highest of those locations
3213// can be written back to the base register.
3214bool
3215EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3216{
3217#if 0
3218    // ARM pseudo code...
3219    if ConditionPassed()
3220        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3221        address = R[n];
3222
3223        for i = 0 to 14
3224            if registers<i> == '1' then
3225                R[i] = MemA[address, 4]; address = address + 4;
3226        if registers<15> == '1' then
3227            LoadWritePC (MemA[address, 4]);
3228
3229        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3230        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3231
3232#endif
3233
3234    bool success = false;
3235
3236    if (ConditionPassed(opcode))
3237    {
3238        uint32_t n;
3239        uint32_t registers = 0;
3240        bool wback;
3241        const uint32_t addr_byte_size = GetAddressByteSize();
3242        switch (encoding)
3243        {
3244            case eEncodingT1:
3245                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3246                n = Bits32 (opcode, 10, 8);
3247                registers = Bits32 (opcode, 7, 0);
3248                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3249                wback = BitIsClear (registers, n);
3250                // if BitCount(registers) < 1 then UNPREDICTABLE;
3251                if (BitCount(registers) < 1)
3252                    return false;
3253                break;
3254            case eEncodingT2:
3255                // if W == '1' && Rn == '1101' then SEE POP;
3256                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3257                n = Bits32 (opcode, 19, 16);
3258                registers = Bits32 (opcode, 15, 0);
3259                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3260                wback = BitIsSet (opcode, 21);
3261
3262                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3263                if ((n == 15)
3264                    || (BitCount (registers) < 2)
3265                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3266                    return false;
3267
3268                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3269                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3270                    return false;
3271
3272                // if wback && registers<n> == '1' then UNPREDICTABLE;
3273                if (wback
3274                    && BitIsSet (registers, n))
3275                    return false;
3276                break;
3277
3278            case eEncodingA1:
3279                n = Bits32 (opcode, 19, 16);
3280                registers = Bits32 (opcode, 15, 0);
3281                wback = BitIsSet (opcode, 21);
3282                if ((n == 15)
3283                    || (BitCount (registers) < 1))
3284                    return false;
3285                break;
3286            default:
3287                return false;
3288        }
3289
3290        int32_t offset = 0;
3291        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3292        if (!success)
3293            return false;
3294
3295        EmulateInstruction::Context context;
3296        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3297        Register dwarf_reg;
3298        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3299        context.SetRegisterPlusOffset (dwarf_reg, offset);
3300
3301        for (int i = 0; i < 14; ++i)
3302        {
3303            if (BitIsSet (registers, i))
3304            {
3305                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3306                context.SetRegisterPlusOffset (dwarf_reg, offset);
3307                if (wback && (n == 13)) // Pop Instruction
3308                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
3309
3310                // R[i] = MemA [address, 4]; address = address + 4;
3311                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3312                if (!success)
3313                    return false;
3314
3315                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3316                    return false;
3317
3318                offset += addr_byte_size;
3319            }
3320        }
3321
3322        if (BitIsSet (registers, 15))
3323        {
3324            //LoadWritePC (MemA [address, 4]);
3325            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3326            context.SetRegisterPlusOffset (dwarf_reg, offset);
3327            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3328            if (!success)
3329                return false;
3330            // In ARMv5T and above, this is an interworking branch.
3331            if (!LoadWritePC(context, data))
3332                return false;
3333        }
3334
3335        if (wback && BitIsClear (registers, n))
3336        {
3337            // R[n] = R[n] + 4 * BitCount (registers)
3338            int32_t offset = addr_byte_size * BitCount (registers);
3339            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3340            context.SetRegisterPlusOffset (dwarf_reg, offset);
3341
3342            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3343                return false;
3344        }
3345        if (wback && BitIsSet (registers, n))
3346            // R[n] bits(32) UNKNOWN;
3347            return WriteBits32Unknown (n);
3348    }
3349    return true;
3350}
3351
3352// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3353// The consecutive memory locations end at this address and the address just below the lowest of those locations
3354// can optionally be written back to the base register.
3355bool
3356EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3357{
3358#if 0
3359    // ARM pseudo code...
3360    if ConditionPassed() then
3361        EncodingSpecificOperations();
3362        address = R[n] - 4*BitCount(registers) + 4;
3363
3364        for i = 0 to 14
3365            if registers<i> == '1' then
3366                  R[i] = MemA[address,4]; address = address + 4;
3367
3368        if registers<15> == '1' then
3369            LoadWritePC(MemA[address,4]);
3370
3371        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3372        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3373#endif
3374
3375    bool success = false;
3376
3377    if (ConditionPassed(opcode))
3378    {
3379        uint32_t n;
3380        uint32_t registers = 0;
3381        bool wback;
3382        const uint32_t addr_byte_size = GetAddressByteSize();
3383
3384        // EncodingSpecificOperations();
3385        switch (encoding)
3386        {
3387            case eEncodingA1:
3388                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3389                n = Bits32 (opcode, 19, 16);
3390                registers = Bits32 (opcode, 15, 0);
3391                wback = BitIsSet (opcode, 21);
3392
3393                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3394                if ((n == 15) || (BitCount (registers) < 1))
3395                    return false;
3396
3397                break;
3398
3399            default:
3400                return false;
3401        }
3402        // address = R[n] - 4*BitCount(registers) + 4;
3403
3404        int32_t offset = 0;
3405        addr_t Rn = ReadCoreReg (n, &success);
3406
3407        if (!success)
3408            return false;
3409
3410        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3411
3412        EmulateInstruction::Context context;
3413        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3414        Register dwarf_reg;
3415        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3416        context.SetRegisterPlusOffset (dwarf_reg, offset);
3417
3418        // for i = 0 to 14
3419        for (int i = 0; i < 14; ++i)
3420        {
3421            // if registers<i> == '1' then
3422            if (BitIsSet (registers, i))
3423            {
3424                  // R[i] = MemA[address,4]; address = address + 4;
3425                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3426                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3427                  if (!success)
3428                      return false;
3429                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3430                      return false;
3431                  offset += addr_byte_size;
3432            }
3433        }
3434
3435        // if registers<15> == '1' then
3436        //     LoadWritePC(MemA[address,4]);
3437        if (BitIsSet (registers, 15))
3438        {
3439            context.SetRegisterPlusOffset (dwarf_reg, offset);
3440            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3441            if (!success)
3442                return false;
3443            // In ARMv5T and above, this is an interworking branch.
3444            if (!LoadWritePC(context, data))
3445                return false;
3446        }
3447
3448        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3449        if (wback && BitIsClear (registers, n))
3450        {
3451            if (!success)
3452                return false;
3453
3454            offset = (addr_byte_size * BitCount (registers)) * -1;
3455            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3456            context.SetImmediateSigned (offset);
3457            addr_t addr = Rn + offset;
3458            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3459                return false;
3460        }
3461
3462        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3463        if (wback && BitIsSet (registers, n))
3464            return WriteBits32Unknown (n);
3465    }
3466    return true;
3467}
3468
3469// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3470// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3471// be optionally written back to the base register.
3472bool
3473EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3474{
3475#if 0
3476    // ARM pseudo code...
3477    if ConditionPassed() then
3478        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3479        address = R[n] - 4*BitCount(registers);
3480
3481        for i = 0 to 14
3482            if registers<i> == '1' then
3483                  R[i] = MemA[address,4]; address = address + 4;
3484        if registers<15> == '1' then
3485                  LoadWritePC(MemA[address,4]);
3486
3487        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3488        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3489#endif
3490
3491    bool success = false;
3492
3493    if (ConditionPassed(opcode))
3494    {
3495        uint32_t n;
3496        uint32_t registers = 0;
3497        bool wback;
3498        const uint32_t addr_byte_size = GetAddressByteSize();
3499        switch (encoding)
3500        {
3501            case eEncodingT1:
3502                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3503                n = Bits32 (opcode, 19, 16);
3504                registers = Bits32 (opcode, 15, 0);
3505                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3506                wback = BitIsSet (opcode, 21);
3507
3508                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3509                if ((n == 15)
3510                    || (BitCount (registers) < 2)
3511                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3512                    return false;
3513
3514                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3515                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3516                    return false;
3517
3518                // if wback && registers<n> == '1' then UNPREDICTABLE;
3519                if (wback && BitIsSet (registers, n))
3520                    return false;
3521
3522                break;
3523
3524            case eEncodingA1:
3525                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3526                n = Bits32 (opcode, 19, 16);
3527                registers = Bits32 (opcode, 15, 0);
3528                wback = BitIsSet (opcode, 21);
3529
3530                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3531                if ((n == 15) || (BitCount (registers) < 1))
3532                    return false;
3533
3534                break;
3535
3536            default:
3537                return false;
3538        }
3539
3540        // address = R[n] - 4*BitCount(registers);
3541
3542        int32_t offset = 0;
3543        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3544
3545        if (!success)
3546            return false;
3547
3548        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3549        EmulateInstruction::Context context;
3550        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3551        Register dwarf_reg;
3552        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3553        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3554
3555        for (int i = 0; i < 14; ++i)
3556        {
3557            if (BitIsSet (registers, i))
3558            {
3559                // R[i] = MemA[address,4]; address = address + 4;
3560                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3561                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3562                if (!success)
3563                    return false;
3564
3565                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3566                    return false;
3567
3568                offset += addr_byte_size;
3569            }
3570        }
3571
3572        // if registers<15> == '1' then
3573        //     LoadWritePC(MemA[address,4]);
3574        if (BitIsSet (registers, 15))
3575        {
3576            context.SetRegisterPlusOffset (dwarf_reg, offset);
3577            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3578            if (!success)
3579                return false;
3580            // In ARMv5T and above, this is an interworking branch.
3581            if (!LoadWritePC(context, data))
3582                return false;
3583        }
3584
3585        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3586        if (wback && BitIsClear (registers, n))
3587        {
3588            if (!success)
3589                return false;
3590
3591            offset = (addr_byte_size * BitCount (registers)) * -1;
3592            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3593            context.SetImmediateSigned (offset);
3594            addr_t addr = Rn + offset;
3595            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3596                return false;
3597        }
3598
3599        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3600        if (wback && BitIsSet (registers, n))
3601            return WriteBits32Unknown (n);
3602    }
3603    return true;
3604}
3605
3606// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3607// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3608// optinoally be written back to the base register.
3609bool
3610EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3611{
3612#if 0
3613    if ConditionPassed() then
3614        EncodingSpecificOperations();
3615        address = R[n] + 4;
3616
3617        for i = 0 to 14
3618            if registers<i> == '1' then
3619                  R[i] = MemA[address,4]; address = address + 4;
3620        if registers<15> == '1' then
3621            LoadWritePC(MemA[address,4]);
3622
3623        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3624        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3625#endif
3626
3627    bool success = false;
3628
3629    if (ConditionPassed(opcode))
3630    {
3631        uint32_t n;
3632        uint32_t registers = 0;
3633        bool wback;
3634        const uint32_t addr_byte_size = GetAddressByteSize();
3635        switch (encoding)
3636        {
3637            case eEncodingA1:
3638                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3639                n = Bits32 (opcode, 19, 16);
3640                registers = Bits32 (opcode, 15, 0);
3641                wback = BitIsSet (opcode, 21);
3642
3643                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3644                if ((n == 15) || (BitCount (registers) < 1))
3645                    return false;
3646
3647                break;
3648            default:
3649                return false;
3650        }
3651        // address = R[n] + 4;
3652
3653        int32_t offset = 0;
3654        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3655
3656        if (!success)
3657            return false;
3658
3659        addr_t address = Rn + addr_byte_size;
3660
3661        EmulateInstruction::Context context;
3662        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3663        Register dwarf_reg;
3664        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3665        context.SetRegisterPlusOffset (dwarf_reg, offset);
3666
3667        for (int i = 0; i < 14; ++i)
3668        {
3669            if (BitIsSet (registers, i))
3670            {
3671                // R[i] = MemA[address,4]; address = address + 4;
3672
3673                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3674                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3675                if (!success)
3676                    return false;
3677
3678                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3679                    return false;
3680
3681                offset += addr_byte_size;
3682            }
3683        }
3684
3685        // if registers<15> == '1' then
3686        //     LoadWritePC(MemA[address,4]);
3687        if (BitIsSet (registers, 15))
3688        {
3689            context.SetRegisterPlusOffset (dwarf_reg, offset);
3690            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3691            if (!success)
3692                return false;
3693            // In ARMv5T and above, this is an interworking branch.
3694            if (!LoadWritePC(context, data))
3695                return false;
3696        }
3697
3698        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3699        if (wback && BitIsClear (registers, n))
3700        {
3701            if (!success)
3702                return false;
3703
3704            offset = addr_byte_size * BitCount (registers);
3705            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3706            context.SetImmediateSigned (offset);
3707            addr_t addr = Rn + offset;
3708            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3709                return false;
3710        }
3711
3712        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3713        if (wback && BitIsSet (registers, n))
3714            return WriteBits32Unknown (n);
3715    }
3716    return true;
3717}
3718
3719// Load Register (immediate) calculates an address from a base register value and
3720// an immediate offset, loads a word from memory, and writes to a register.
3721// LDR (immediate, Thumb)
3722bool
3723EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3724{
3725#if 0
3726    // ARM pseudo code...
3727    if (ConditionPassed())
3728    {
3729        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3730        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3731        address = if index then offset_addr else R[n];
3732        data = MemU[address,4];
3733        if wback then R[n] = offset_addr;
3734        if t == 15 then
3735            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3736        elsif UnalignedSupport() || address<1:0> = '00' then
3737            R[t] = data;
3738        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3739    }
3740#endif
3741
3742    bool success = false;
3743
3744    if (ConditionPassed(opcode))
3745    {
3746        uint32_t Rt; // the destination register
3747        uint32_t Rn; // the base register
3748        uint32_t imm32; // the immediate offset used to form the address
3749        addr_t offset_addr; // the offset address
3750        addr_t address; // the calculated address
3751        uint32_t data; // the literal data value from memory load
3752        bool add, index, wback;
3753        switch (encoding) {
3754            case eEncodingT1:
3755                Rt = Bits32(opcode, 2, 0);
3756                Rn = Bits32(opcode, 5, 3);
3757                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3758                // index = TRUE; add = TRUE; wback = FALSE
3759                add = true;
3760                index = true;
3761                wback = false;
3762
3763                break;
3764
3765            case eEncodingT2:
3766                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3767                Rt = Bits32 (opcode, 10, 8);
3768                Rn = 13;
3769                imm32 = Bits32 (opcode, 7, 0) << 2;
3770
3771                // index = TRUE; add = TRUE; wback = FALSE;
3772                index = true;
3773                add = true;
3774                wback = false;
3775
3776                break;
3777
3778            case eEncodingT3:
3779                // if Rn == '1111' then SEE LDR (literal);
3780                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3781                Rt = Bits32 (opcode, 15, 12);
3782                Rn = Bits32 (opcode, 19, 16);
3783                imm32 = Bits32 (opcode, 11, 0);
3784
3785                // index = TRUE; add = TRUE; wback = FALSE;
3786                index = true;
3787                add = true;
3788                wback = false;
3789
3790                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3791                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3792                    return false;
3793
3794                break;
3795
3796            case eEncodingT4:
3797                // if Rn == '1111' then SEE LDR (literal);
3798                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3799                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3800                // if P == '0' && W == '0' then UNDEFINED;
3801                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3802                    return false;
3803
3804                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3805                Rt = Bits32 (opcode, 15, 12);
3806                Rn = Bits32 (opcode, 19, 16);
3807                imm32 = Bits32 (opcode, 7, 0);
3808
3809                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3810                index = BitIsSet (opcode, 10);
3811                add = BitIsSet (opcode, 9);
3812                wback = BitIsSet (opcode, 8);
3813
3814                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3815                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3816                    return false;
3817
3818                break;
3819
3820            default:
3821                return false;
3822        }
3823        uint32_t base = ReadCoreReg (Rn, &success);
3824        if (!success)
3825            return false;
3826        if (add)
3827            offset_addr = base + imm32;
3828        else
3829            offset_addr = base - imm32;
3830
3831        address = (index ? offset_addr : base);
3832
3833        Register base_reg;
3834        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
3835        if (wback)
3836        {
3837            EmulateInstruction::Context ctx;
3838            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3839            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3840
3841            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3842                return false;
3843        }
3844
3845        // Prepare to write to the Rt register.
3846        EmulateInstruction::Context context;
3847        context.type = EmulateInstruction::eContextRegisterLoad;
3848        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3849
3850        // Read memory from the address.
3851        data = MemURead(context, address, 4, 0, &success);
3852        if (!success)
3853            return false;
3854
3855        if (Rt == 15)
3856        {
3857            if (Bits32(address, 1, 0) == 0)
3858            {
3859                if (!LoadWritePC(context, data))
3860                    return false;
3861            }
3862            else
3863                return false;
3864        }
3865        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3866        {
3867            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3868                return false;
3869        }
3870        else
3871            WriteBits32Unknown (Rt);
3872    }
3873    return true;
3874}
3875
3876// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3877// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3878// of those locations can optionally be written back to the base register.
3879bool
3880EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3881{
3882#if 0
3883    if ConditionPassed() then
3884        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3885        address = R[n];
3886
3887        for i = 0 to 14
3888            if registers<i> == '1' then
3889                if i == n && wback && i != LowestSetBit(registers) then
3890                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3891                else
3892                    MemA[address,4] = R[i];
3893                address = address + 4;
3894
3895        if registers<15> == '1' then // Only possible for encoding A1
3896            MemA[address,4] = PCStoreValue();
3897        if wback then R[n] = R[n] + 4*BitCount(registers);
3898#endif
3899
3900    bool success = false;
3901
3902    if (ConditionPassed(opcode))
3903    {
3904        uint32_t n;
3905        uint32_t registers = 0;
3906        bool wback;
3907        const uint32_t addr_byte_size = GetAddressByteSize();
3908
3909        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3910        switch (encoding)
3911        {
3912            case eEncodingT1:
3913                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
3914                n = Bits32 (opcode, 10, 8);
3915                registers = Bits32 (opcode, 7, 0);
3916                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3917                wback = true;
3918
3919                // if BitCount(registers) < 1 then UNPREDICTABLE;
3920                if (BitCount (registers) < 1)
3921                    return false;
3922
3923                break;
3924
3925            case eEncodingT2:
3926                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
3927                n = Bits32 (opcode, 19, 16);
3928                registers = Bits32 (opcode, 15, 0);
3929                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3930                wback = BitIsSet (opcode, 21);
3931
3932                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3933                if ((n == 15) || (BitCount (registers) < 2))
3934                    return false;
3935
3936                // if wback && registers<n> == '1' then UNPREDICTABLE;
3937                if (wback && BitIsSet (registers, n))
3938                    return false;
3939
3940                break;
3941
3942            case eEncodingA1:
3943                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3944                n = Bits32 (opcode, 19, 16);
3945                registers = Bits32 (opcode, 15, 0);
3946                wback = BitIsSet (opcode, 21);
3947
3948                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3949                if ((n == 15) || (BitCount (registers) < 1))
3950                    return false;
3951
3952                break;
3953
3954            default:
3955                return false;
3956        }
3957
3958        // address = R[n];
3959        int32_t offset = 0;
3960        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3961        if (!success)
3962            return false;
3963
3964        EmulateInstruction::Context context;
3965        context.type = EmulateInstruction::eContextRegisterStore;
3966        Register base_reg;
3967        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3968
3969        // for i = 0 to 14
3970        int lowest_set_bit = 14;
3971        for (int i = 0; i < 14; ++i)
3972        {
3973            // if registers<i> == '1' then
3974            if (BitIsSet (registers, i))
3975            {
3976                  if (i < lowest_set_bit)
3977                      lowest_set_bit = i;
3978                  // if i == n && wback && i != LowestSetBit(registers) then
3979                  if ((i == n) && wback && (i != lowest_set_bit))
3980                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3981                      WriteBits32UnknownToMemory (address + offset);
3982                  else
3983                  {
3984                     // MemA[address,4] = R[i];
3985                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3986                      if (!success)
3987                          return false;
3988
3989                      Register data_reg;
3990                      data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3991                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3992                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
3993                          return false;
3994                  }
3995
3996                  // address = address + 4;
3997                  offset += addr_byte_size;
3998            }
3999        }
4000
4001        // if registers<15> == '1' then // Only possible for encoding A1
4002        //     MemA[address,4] = PCStoreValue();
4003        if (BitIsSet (registers, 15))
4004        {
4005            Register pc_reg;
4006            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4007            context.SetRegisterPlusOffset (pc_reg, 8);
4008            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4009            if (!success)
4010                return false;
4011
4012            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4013                return false;
4014        }
4015
4016        // if wback then R[n] = R[n] + 4*BitCount(registers);
4017        if (wback)
4018        {
4019            offset = addr_byte_size * BitCount (registers);
4020            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4021            context.SetImmediateSigned (offset);
4022            addr_t data = address + offset;
4023            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4024                return false;
4025        }
4026    }
4027    return true;
4028}
4029
4030// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4031// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4032// of those locations can optionally be written back to the base register.
4033bool
4034EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4035{
4036#if 0
4037    if ConditionPassed() then
4038        EncodingSpecificOperations();
4039        address = R[n] - 4*BitCount(registers) + 4;
4040
4041        for i = 0 to 14
4042            if registers<i> == '1' then
4043                if i == n && wback && i != LowestSetBit(registers) then
4044                    MemA[address,4] = bits(32) UNKNOWN;
4045                else
4046                    MemA[address,4] = R[i];
4047                address = address + 4;
4048
4049        if registers<15> == '1' then
4050            MemA[address,4] = PCStoreValue();
4051
4052        if wback then R[n] = R[n] - 4*BitCount(registers);
4053#endif
4054
4055    bool success = false;
4056
4057    if (ConditionPassed(opcode))
4058    {
4059        uint32_t n;
4060        uint32_t registers = 0;
4061        bool wback;
4062        const uint32_t addr_byte_size = GetAddressByteSize();
4063
4064        // EncodingSpecificOperations();
4065        switch (encoding)
4066        {
4067            case eEncodingA1:
4068                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4069                n = Bits32 (opcode, 19, 16);
4070                registers = Bits32 (opcode, 15, 0);
4071                wback = BitIsSet (opcode, 21);
4072
4073                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4074                if ((n == 15) || (BitCount (registers) < 1))
4075                    return false;
4076                break;
4077            default:
4078                return false;
4079        }
4080
4081        // address = R[n] - 4*BitCount(registers) + 4;
4082        int32_t offset = 0;
4083        addr_t Rn = ReadCoreReg (n, &success);
4084        if (!success)
4085            return false;
4086
4087        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4088
4089        EmulateInstruction::Context context;
4090        context.type = EmulateInstruction::eContextRegisterStore;
4091        Register base_reg;
4092        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4093
4094        // for i = 0 to 14
4095        int lowest_bit_set = 14;
4096        for (int i = 0; i < 14; ++i)
4097        {
4098            // if registers<i> == '1' then
4099            if (BitIsSet (registers, i))
4100            {
4101                if (i < lowest_bit_set)
4102                    lowest_bit_set = i;
4103                //if i == n && wback && i != LowestSetBit(registers) then
4104                if ((i == n) && wback && (i != lowest_bit_set))
4105                    // MemA[address,4] = bits(32) UNKNOWN;
4106                    WriteBits32UnknownToMemory (address + offset);
4107                else
4108                {
4109                    // MemA[address,4] = R[i];
4110                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4111                    if (!success)
4112                        return false;
4113
4114                    Register data_reg;
4115                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4116                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4117                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4118                        return false;
4119                }
4120
4121                // address = address + 4;
4122                offset += addr_byte_size;
4123            }
4124        }
4125
4126        // if registers<15> == '1' then
4127        //    MemA[address,4] = PCStoreValue();
4128        if (BitIsSet (registers, 15))
4129        {
4130            Register pc_reg;
4131            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4132            context.SetRegisterPlusOffset (pc_reg, 8);
4133            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4134            if (!success)
4135                return false;
4136
4137            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4138                return false;
4139        }
4140
4141        // if wback then R[n] = R[n] - 4*BitCount(registers);
4142        if (wback)
4143        {
4144            offset = (addr_byte_size * BitCount (registers)) * -1;
4145            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4146            context.SetImmediateSigned (offset);
4147            addr_t data = Rn + offset;
4148            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4149                return false;
4150        }
4151    }
4152    return true;
4153}
4154
4155// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4156// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4157// those locations can optionally be written back to the base register.
4158bool
4159EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4160{
4161#if 0
4162    if ConditionPassed() then
4163        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4164        address = R[n] - 4*BitCount(registers);
4165
4166        for i = 0 to 14
4167            if registers<i> == '1' then
4168                if i == n && wback && i != LowestSetBit(registers) then
4169                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4170                else
4171                    MemA[address,4] = R[i];
4172                address = address + 4;
4173
4174        if registers<15> == '1' then // Only possible for encoding A1
4175            MemA[address,4] = PCStoreValue();
4176
4177        if wback then R[n] = R[n] - 4*BitCount(registers);
4178#endif
4179
4180
4181    bool success = false;
4182
4183    if (ConditionPassed(opcode))
4184    {
4185        uint32_t n;
4186        uint32_t registers = 0;
4187        bool wback;
4188        const uint32_t addr_byte_size = GetAddressByteSize();
4189
4190        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4191        switch (encoding)
4192        {
4193            case eEncodingT1:
4194                // if W == '1' && Rn == '1101' then SEE PUSH;
4195                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4196                {
4197                    // See PUSH
4198                }
4199                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4200                n = Bits32 (opcode, 19, 16);
4201                registers = Bits32 (opcode, 15, 0);
4202                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4203                wback = BitIsSet (opcode, 21);
4204                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4205                if ((n == 15) || BitCount (registers) < 2)
4206                    return false;
4207                // if wback && registers<n> == '1' then UNPREDICTABLE;
4208                if (wback && BitIsSet (registers, n))
4209                    return false;
4210                break;
4211
4212            case eEncodingA1:
4213                // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH;
4214                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4215                {
4216                    // See Push
4217                }
4218                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4219                n = Bits32 (opcode, 19, 16);
4220                registers = Bits32 (opcode, 15, 0);
4221                wback = BitIsSet (opcode, 21);
4222                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4223                if ((n == 15) || BitCount (registers) < 1)
4224                    return false;
4225                break;
4226
4227            default:
4228                return false;
4229        }
4230
4231        // address = R[n] - 4*BitCount(registers);
4232
4233        int32_t offset = 0;
4234        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4235        if (!success)
4236        return false;
4237
4238        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4239
4240        EmulateInstruction::Context context;
4241        context.type = EmulateInstruction::eContextRegisterStore;
4242        Register base_reg;
4243        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4244
4245        // for i = 0 to 14
4246        uint32_t lowest_set_bit = 14;
4247        for (int i = 0; i < 14; ++i)
4248        {
4249            // if registers<i> == '1' then
4250            if (BitIsSet (registers, i))
4251            {
4252                if (i < lowest_set_bit)
4253                    lowest_set_bit = i;
4254                // if i == n && wback && i != LowestSetBit(registers) then
4255                if ((i == n) && wback && (i != lowest_set_bit))
4256                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4257                    WriteBits32UnknownToMemory (address + offset);
4258                else
4259                {
4260                    // MemA[address,4] = R[i];
4261                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4262                    if (!success)
4263                        return false;
4264
4265                    Register data_reg;
4266                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4267                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4268                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4269                        return false;
4270                }
4271
4272                // address = address + 4;
4273                offset += addr_byte_size;
4274            }
4275        }
4276
4277        // if registers<15> == '1' then // Only possible for encoding A1
4278        //     MemA[address,4] = PCStoreValue();
4279        if (BitIsSet (registers, 15))
4280        {
4281            Register pc_reg;
4282            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4283            context.SetRegisterPlusOffset (pc_reg, 8);
4284            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4285            if (!success)
4286                return false;
4287
4288            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4289                return false;
4290        }
4291
4292        // if wback then R[n] = R[n] - 4*BitCount(registers);
4293        if (wback)
4294        {
4295            offset = (addr_byte_size * BitCount (registers)) * -1;
4296            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4297            context.SetImmediateSigned (offset);
4298            addr_t data = Rn + offset;
4299            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4300                return false;
4301        }
4302    }
4303    return true;
4304}
4305
4306// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4307// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4308// of those locations can optionally be written back to the base register.
4309bool
4310EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4311{
4312#if 0
4313    if ConditionPassed() then
4314        EncodingSpecificOperations();
4315        address = R[n] + 4;
4316
4317        for i = 0 to 14
4318            if registers<i> == '1' then
4319                if i == n && wback && i != LowestSetBit(registers) then
4320                    MemA[address,4] = bits(32) UNKNOWN;
4321                else
4322                    MemA[address,4] = R[i];
4323                address = address + 4;
4324
4325        if registers<15> == '1' then
4326            MemA[address,4] = PCStoreValue();
4327
4328        if wback then R[n] = R[n] + 4*BitCount(registers);
4329#endif
4330
4331    bool success = false;
4332
4333    if (ConditionPassed(opcode))
4334    {
4335        uint32_t n;
4336        uint32_t registers = 0;
4337        bool wback;
4338        const uint32_t addr_byte_size = GetAddressByteSize();
4339
4340        // EncodingSpecificOperations();
4341        switch (encoding)
4342        {
4343            case eEncodingA1:
4344                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4345                n = Bits32 (opcode, 19, 16);
4346                registers = Bits32 (opcode, 15, 0);
4347                wback = BitIsSet (opcode, 21);
4348
4349                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4350                if ((n == 15) && (BitCount (registers) < 1))
4351                    return false;
4352                break;
4353            default:
4354                return false;
4355        }
4356        // address = R[n] + 4;
4357
4358        int32_t offset = 0;
4359        addr_t Rn = ReadCoreReg (n, &success);
4360        if (!success)
4361            return false;
4362
4363        addr_t address = Rn + addr_byte_size;
4364
4365        EmulateInstruction::Context context;
4366        context.type = EmulateInstruction::eContextRegisterStore;
4367        Register base_reg;
4368        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4369
4370        uint32_t lowest_set_bit = 14;
4371        // for i = 0 to 14
4372        for (int i = 0; i < 14; ++i)
4373        {
4374            // if registers<i> == '1' then
4375            if (BitIsSet (registers, i))
4376            {
4377                if (i < lowest_set_bit)
4378                    lowest_set_bit = i;
4379                // if i == n && wback && i != LowestSetBit(registers) then
4380                if ((i == n) && wback && (i != lowest_set_bit))
4381                    // MemA[address,4] = bits(32) UNKNOWN;
4382                    WriteBits32UnknownToMemory (address + offset);
4383                // else
4384                else
4385                {
4386                    // MemA[address,4] = R[i];
4387                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4388                    if (!success)
4389                        return false;
4390
4391                    Register data_reg;
4392                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4393                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4394                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4395                        return false;
4396                }
4397
4398                // address = address + 4;
4399                offset += addr_byte_size;
4400            }
4401        }
4402
4403        // if registers<15> == '1' then
4404            // MemA[address,4] = PCStoreValue();
4405        if (BitIsSet (registers, 15))
4406        {
4407            Register pc_reg;
4408            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4409            context.SetRegisterPlusOffset (pc_reg, 8);
4410            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4411            if (!success)
4412            return false;
4413
4414            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4415                return false;
4416        }
4417
4418        // if wback then R[n] = R[n] + 4*BitCount(registers);
4419        if (wback)
4420        {
4421            offset = addr_byte_size * BitCount (registers);
4422            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4423            context.SetImmediateSigned (offset);
4424            addr_t data = Rn + offset;
4425            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4426                return false;
4427        }
4428    }
4429    return true;
4430}
4431
4432// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4433// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4434bool
4435EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4436{
4437#if 0
4438    if ConditionPassed() then
4439        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4440        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4441        address = if index then offset_addr else R[n];
4442        if UnalignedSupport() || address<1:0> == '00' then
4443            MemU[address,4] = R[t];
4444        else // Can only occur before ARMv7
4445            MemU[address,4] = bits(32) UNKNOWN;
4446        if wback then R[n] = offset_addr;
4447#endif
4448
4449    bool success = false;
4450
4451    if (ConditionPassed(opcode))
4452    {
4453        const uint32_t addr_byte_size = GetAddressByteSize();
4454
4455        uint32_t t;
4456        uint32_t n;
4457        uint32_t imm32;
4458        bool index;
4459        bool add;
4460        bool wback;
4461        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4462        switch (encoding)
4463        {
4464            case eEncodingT1:
4465                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4466                t = Bits32 (opcode, 2, 0);
4467                n = Bits32 (opcode, 5, 3);
4468                imm32 = Bits32 (opcode, 10, 6) << 2;
4469
4470                // index = TRUE; add = TRUE; wback = FALSE;
4471                index = true;
4472                add = false;
4473                wback = false;
4474                break;
4475
4476            case eEncodingT2:
4477                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4478                t = Bits32 (opcode, 10, 8);
4479                n = 13;
4480                imm32 = Bits32 (opcode, 7, 0) << 2;
4481
4482                // index = TRUE; add = TRUE; wback = FALSE;
4483                index = true;
4484                add = true;
4485                wback = false;
4486                break;
4487
4488            case eEncodingT3:
4489                // if Rn == '1111' then UNDEFINED;
4490                if (Bits32 (opcode, 19, 16) == 15)
4491                    return false;
4492
4493                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4494                t = Bits32 (opcode, 15, 12);
4495                n = Bits32 (opcode, 19, 16);
4496                imm32 = Bits32 (opcode, 11, 0);
4497
4498                // index = TRUE; add = TRUE; wback = FALSE;
4499                index = true;
4500                add = true;
4501                wback = false;
4502
4503                // if t == 15 then UNPREDICTABLE;
4504                if (t == 15)
4505                    return false;
4506                break;
4507
4508            case eEncodingT4:
4509                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4510                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4511                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4512                if ((Bits32 (opcode, 19, 16) == 15)
4513                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4514                    return false;
4515
4516                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4517                t = Bits32 (opcode, 15, 12);
4518                n = Bits32 (opcode, 19, 16);
4519                imm32 = Bits32 (opcode, 7, 0);
4520
4521                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4522                index = BitIsSet (opcode, 10);
4523                add = BitIsSet (opcode, 9);
4524                wback = BitIsSet (opcode, 8);
4525
4526                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4527                if ((t == 15) || (wback && (n == t)))
4528                    return false;
4529                break;
4530
4531            default:
4532                return false;
4533        }
4534
4535        addr_t offset_addr;
4536        addr_t address;
4537
4538        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4539        uint32_t base_address = ReadCoreReg (n, &success);
4540        if (!success)
4541            return false;
4542
4543        if (add)
4544            offset_addr = base_address + imm32;
4545        else
4546            offset_addr = base_address - imm32;
4547
4548        // address = if index then offset_addr else R[n];
4549        if (index)
4550            address = offset_addr;
4551        else
4552            address = base_address;
4553
4554        EmulateInstruction::Context context;
4555        context.type = eContextRegisterStore;
4556        Register base_reg;
4557        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4558
4559        // if UnalignedSupport() || address<1:0> == '00' then
4560        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4561        {
4562            // MemU[address,4] = R[t];
4563            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4564            if (!success)
4565                return false;
4566
4567            Register data_reg;
4568            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4569            int32_t offset = address - base_address;
4570            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4571            if (!MemUWrite (context, address, data, addr_byte_size))
4572                return false;
4573        }
4574        else
4575        {
4576            // MemU[address,4] = bits(32) UNKNOWN;
4577            WriteBits32UnknownToMemory (address);
4578        }
4579
4580        // if wback then R[n] = offset_addr;
4581        if (wback)
4582        {
4583            context.type = eContextRegisterLoad;
4584            context.SetAddress (offset_addr);
4585            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4586                return false;
4587        }
4588    }
4589    return true;
4590}
4591
4592// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4593// word from a register to memory.   The offset register value can optionally be shifted.
4594bool
4595EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4596{
4597#if 0
4598    if ConditionPassed() then
4599        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4600        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4601        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4602        address = if index then offset_addr else R[n];
4603        if t == 15 then // Only possible for encoding A1
4604            data = PCStoreValue();
4605        else
4606            data = R[t];
4607        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4608            MemU[address,4] = data;
4609        else // Can only occur before ARMv7
4610            MemU[address,4] = bits(32) UNKNOWN;
4611        if wback then R[n] = offset_addr;
4612#endif
4613
4614    bool success = false;
4615
4616    if (ConditionPassed(opcode))
4617    {
4618        const uint32_t addr_byte_size = GetAddressByteSize();
4619
4620        uint32_t t;
4621        uint32_t n;
4622        uint32_t m;
4623        ARM_ShifterType shift_t;
4624        uint32_t shift_n;
4625        bool index;
4626        bool add;
4627        bool wback;
4628
4629        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4630        switch (encoding)
4631        {
4632            case eEncodingT1:
4633                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4634                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4635                t = Bits32 (opcode, 2, 0);
4636                n = Bits32 (opcode, 5, 3);
4637                m = Bits32 (opcode, 8, 6);
4638
4639                // index = TRUE; add = TRUE; wback = FALSE;
4640                index = true;
4641                add = true;
4642                wback = false;
4643
4644                // (shift_t, shift_n) = (SRType_LSL, 0);
4645                shift_t = SRType_LSL;
4646                shift_n = 0;
4647                break;
4648
4649            case eEncodingT2:
4650                // if Rn == '1111' then UNDEFINED;
4651                if (Bits32 (opcode, 19, 16) == 15)
4652                    return false;
4653
4654                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4655                t = Bits32 (opcode, 15, 12);
4656                n = Bits32 (opcode, 19, 16);
4657                m = Bits32 (opcode, 3, 0);
4658
4659                // index = TRUE; add = TRUE; wback = FALSE;
4660                index = true;
4661                add = true;
4662                wback = false;
4663
4664                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4665                shift_t = SRType_LSL;
4666                shift_n = Bits32 (opcode, 5, 4);
4667
4668                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4669                if ((t == 15) || (BadReg (m)))
4670                    return false;
4671                break;
4672
4673            case eEncodingA1:
4674            {
4675                // if P == '0' && W == '1' then SEE STRT;
4676                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4677                t = Bits32 (opcode, 15, 12);
4678                n = Bits32 (opcode, 19, 16);
4679                m = Bits32 (opcode, 3, 0);
4680
4681                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4682                index = BitIsSet (opcode, 24);
4683                add = BitIsSet (opcode, 23);
4684                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4685
4686                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4687                uint32_t typ = Bits32 (opcode, 6, 5);
4688                uint32_t imm5 = Bits32 (opcode, 11, 7);
4689                shift_n = DecodeImmShift(typ, imm5, shift_t);
4690
4691                // if m == 15 then UNPREDICTABLE;
4692                if (m == 15)
4693                    return false;
4694
4695                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4696                if (wback && ((n == 15) || (n == t)))
4697                    return false;
4698
4699                break;
4700            }
4701            default:
4702                return false;
4703        }
4704
4705        addr_t offset_addr;
4706        addr_t address;
4707        int32_t offset = 0;
4708
4709        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4710        if (!success)
4711            return false;
4712
4713        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4714        if (!success)
4715            return false;
4716
4717        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4718        offset = Shift (Rm_data, shift_t, shift_n, APSR_C);
4719
4720        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4721        if (add)
4722            offset_addr = base_address + offset;
4723        else
4724            offset_addr = base_address - offset;
4725
4726        // address = if index then offset_addr else R[n];
4727        if (index)
4728            address = offset_addr;
4729        else
4730            address = base_address;
4731
4732        uint32_t data;
4733        // if t == 15 then // Only possible for encoding A1
4734        if (t == 15)
4735            // data = PCStoreValue();
4736            data = ReadCoreReg (PC_REG, &success);
4737        else
4738            // data = R[t];
4739            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4740
4741        if (!success)
4742            return false;
4743
4744        EmulateInstruction::Context context;
4745        context.type = eContextRegisterStore;
4746
4747        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4748        if (UnalignedSupport ()
4749            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4750            || CurrentInstrSet() == eModeARM)
4751        {
4752            // MemU[address,4] = data;
4753
4754            Register base_reg;
4755            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4756
4757            Register data_reg;
4758            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4759
4760            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4761            if (!MemUWrite (context, address, data, addr_byte_size))
4762                return false;
4763
4764        }
4765        else
4766            // MemU[address,4] = bits(32) UNKNOWN;
4767            WriteBits32UnknownToMemory (address);
4768
4769        // if wback then R[n] = offset_addr;
4770        if (wback)
4771        {
4772            context.type = eContextRegisterLoad;
4773            context.SetAddress (offset_addr);
4774            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4775                return false;
4776        }
4777
4778    }
4779    return true;
4780}
4781
4782bool
4783EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4784{
4785#if 0
4786    if ConditionPassed() then
4787        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4788        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4789        address = if index then offset_addr else R[n];
4790        MemU[address,1] = R[t]<7:0>;
4791        if wback then R[n] = offset_addr;
4792#endif
4793
4794
4795    bool success = false;
4796
4797    if (ConditionPassed(opcode))
4798    {
4799        uint32_t t;
4800        uint32_t n;
4801        uint32_t imm32;
4802        bool index;
4803        bool add;
4804        bool wback;
4805        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4806        switch (encoding)
4807        {
4808            case eEncodingT1:
4809                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4810                t = Bits32 (opcode, 2, 0);
4811                n = Bits32 (opcode, 5, 3);
4812                imm32 = Bits32 (opcode, 10, 6);
4813
4814                // index = TRUE; add = TRUE; wback = FALSE;
4815                index = true;
4816                add = true;
4817                wback = false;
4818                break;
4819
4820            case eEncodingT2:
4821                // if Rn == '1111' then UNDEFINED;
4822                if (Bits32 (opcode, 19, 16) == 15)
4823                    return false;
4824
4825                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4826                t = Bits32 (opcode, 15, 12);
4827                n = Bits32 (opcode, 19, 16);
4828                imm32 = Bits32 (opcode, 11, 0);
4829
4830                // index = TRUE; add = TRUE; wback = FALSE;
4831                index = true;
4832                add = true;
4833                wback = false;
4834
4835                // if BadReg(t) then UNPREDICTABLE;
4836                if (BadReg (t))
4837                    return false;
4838                break;
4839
4840            case eEncodingT3:
4841                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4842                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4843                if (Bits32 (opcode, 19, 16) == 15)
4844                    return false;
4845
4846                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4847                t = Bits32 (opcode, 15, 12);
4848                n = Bits32 (opcode, 19, 16);
4849                imm32 = Bits32 (opcode, 7, 0);
4850
4851                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4852                index = BitIsSet (opcode, 10);
4853                add = BitIsSet (opcode, 9);
4854                wback = BitIsSet (opcode, 8);
4855
4856                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4857                if ((BadReg (t)) || (wback && (n == t)))
4858                    return false;
4859                break;
4860
4861            default:
4862                return false;
4863        }
4864
4865        addr_t offset_addr;
4866        addr_t address;
4867        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4868        if (!success)
4869            return false;
4870
4871        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4872        if (add)
4873            offset_addr = base_address + imm32;
4874        else
4875            offset_addr = base_address - imm32;
4876
4877        // address = if index then offset_addr else R[n];
4878        if (index)
4879            address = offset_addr;
4880        else
4881            address = base_address;
4882
4883        // MemU[address,1] = R[t]<7:0>
4884        Register base_reg;
4885        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4886
4887        Register data_reg;
4888        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4889
4890        EmulateInstruction::Context context;
4891        context.type = eContextRegisterStore;
4892        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4893
4894        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4895        if (!success)
4896            return false;
4897
4898        data = Bits32 (data, 7, 0);
4899
4900        if (!MemUWrite (context, address, data, 1))
4901            return false;
4902
4903        // if wback then R[n] = offset_addr;
4904        if (wback)
4905        {
4906            context.type = eContextRegisterLoad;
4907            context.SetAddress (offset_addr);
4908            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4909                return false;
4910        }
4911
4912    }
4913
4914    return true;
4915}
4916
4917// STRH (register) calculates an address from a base register value and an offset register value, and stores a
4918// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
4919bool
4920EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
4921{
4922#if 0
4923    if ConditionPassed() then
4924        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4925        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4926        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4927        address = if index then offset_addr else R[n];
4928        if UnalignedSupport() || address<0> == '0' then
4929            MemU[address,2] = R[t]<15:0>;
4930        else // Can only occur before ARMv7
4931            MemU[address,2] = bits(16) UNKNOWN;
4932        if wback then R[n] = offset_addr;
4933#endif
4934
4935    bool success = false;
4936
4937    if (ConditionPassed(opcode))
4938    {
4939        uint32_t t;
4940        uint32_t n;
4941        uint32_t m;
4942        bool index;
4943        bool add;
4944        bool wback;
4945        ARM_ShifterType shift_t;
4946        uint32_t shift_n;
4947
4948        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4949        switch (encoding)
4950        {
4951            case eEncodingT1:
4952                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4953                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4954                t = Bits32 (opcode, 2, 0);
4955                n = Bits32 (opcode, 5, 3);
4956                m = Bits32 (opcode, 8, 6);
4957
4958                // index = TRUE; add = TRUE; wback = FALSE;
4959                index = true;
4960                add = true;
4961                wback = false;
4962
4963                // (shift_t, shift_n) = (SRType_LSL, 0);
4964                shift_t = SRType_LSL;
4965                shift_n = 0;
4966
4967                break;
4968
4969            case eEncodingT2:
4970                // if Rn == '1111' then UNDEFINED;
4971                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4972                t = Bits32 (opcode, 15, 12);
4973                n = Bits32 (opcode, 19, 16);
4974                m = Bits32 (opcode, 3, 0);
4975                if (n == 15)
4976                    return false;
4977
4978                // index = TRUE; add = TRUE; wback = FALSE;
4979                index = true;
4980                add = true;
4981                wback = false;
4982
4983                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4984                shift_t = SRType_LSL;
4985                shift_n = Bits32 (opcode, 5, 4);
4986
4987                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
4988                if (BadReg (t) || BadReg (m))
4989                    return false;
4990
4991                break;
4992
4993            case eEncodingA1:
4994                // if P == '0' && W == '1' then SEE STRHT;
4995                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4996                t = Bits32 (opcode, 15, 12);
4997                n = Bits32 (opcode, 19, 16);
4998                m = Bits32 (opcode, 3, 0);
4999
5000                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5001                index = BitIsSet (opcode, 24);
5002                add = BitIsSet (opcode, 23);
5003                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5004
5005                // (shift_t, shift_n) = (SRType_LSL, 0);
5006                shift_t = SRType_LSL;
5007                shift_n = 0;
5008
5009                // if t == 15 || m == 15 then UNPREDICTABLE;
5010                if ((t == 15) || (m == 15))
5011                    return false;
5012
5013                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5014                if (wback && ((n == 15) || (n == t)))
5015                    return false;
5016
5017                break;
5018
5019            default:
5020                return false;
5021        }
5022
5023        uint32_t Rm = ReadCoreReg (m, &success);
5024        if (!success)
5025            return false;
5026
5027        uint32_t Rn = ReadCoreReg (n, &success);
5028        if (!success)
5029            return false;
5030
5031        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5032        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
5033
5034        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5035        addr_t offset_addr;
5036        if (add)
5037            offset_addr = Rn + offset;
5038        else
5039            offset_addr = Rn - offset;
5040
5041        // address = if index then offset_addr else R[n];
5042        addr_t address;
5043        if (index)
5044            address = offset_addr;
5045        else
5046            address = Rn;
5047
5048        EmulateInstruction::Context context;
5049        context.type = eContextRegisterStore;
5050        Register base_reg;
5051        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5052        Register offset_reg;
5053        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5054
5055        // if UnalignedSupport() || address<0> == '0' then
5056        if (UnalignedSupport() || BitIsClear (address, 0))
5057        {
5058            // MemU[address,2] = R[t]<15:0>;
5059            uint32_t Rt = ReadCoreReg (t, &success);
5060            if (!success)
5061                return false;
5062
5063            EmulateInstruction::Context context;
5064            context.type = eContextRegisterStore;
5065            Register base_reg;
5066            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5067            Register offset_reg;
5068            offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5069            Register data_reg;
5070            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
5071            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5072
5073            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5074                return false;
5075        }
5076        else // Can only occur before ARMv7
5077        {
5078            // MemU[address,2] = bits(16) UNKNOWN;
5079        }
5080
5081        // if wback then R[n] = offset_addr;
5082        if (wback)
5083        {
5084            context.type = eContextAdjustBaseRegister;
5085            context.SetAddress (offset_addr);
5086            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5087                return false;
5088        }
5089    }
5090
5091    return true;
5092}
5093
5094// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5095// and writes the result to the destination register.  It can optionally update the condition flags
5096// based on the result.
5097bool
5098EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5099{
5100#if 0
5101    // ARM pseudo code...
5102    if ConditionPassed() then
5103        EncodingSpecificOperations();
5104        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5105        if d == 15 then         // Can only occur for ARM encoding
5106            ALUWritePC(result); // setflags is always FALSE here
5107        else
5108            R[d] = result;
5109            if setflags then
5110                APSR.N = result<31>;
5111                APSR.Z = IsZeroBit(result);
5112                APSR.C = carry;
5113                APSR.V = overflow;
5114#endif
5115
5116    bool success = false;
5117
5118    if (ConditionPassed(opcode))
5119    {
5120        uint32_t Rd, Rn;
5121        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5122        bool setflags;
5123        switch (encoding)
5124        {
5125        case eEncodingT1:
5126            Rd = Bits32(opcode, 11, 8);
5127            Rn = Bits32(opcode, 19, 16);
5128            setflags = BitIsSet(opcode, 20);
5129            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5130            if (BadReg(Rd) || BadReg(Rn))
5131                return false;
5132            break;
5133        case eEncodingA1:
5134            Rd = Bits32(opcode, 15, 12);
5135            Rn = Bits32(opcode, 19, 16);
5136            setflags = BitIsSet(opcode, 20);
5137            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5138
5139            if (Rd == 15 && setflags)
5140                return EmulateSUBSPcLrEtc (opcode, encoding);
5141            break;
5142        default:
5143            return false;
5144        }
5145
5146        // Read the first operand.
5147        int32_t val1 = ReadCoreReg(Rn, &success);
5148        if (!success)
5149            return false;
5150
5151        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5152
5153        EmulateInstruction::Context context;
5154        context.type = EmulateInstruction::eContextImmediate;
5155        context.SetNoArgs ();
5156
5157        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5158            return false;
5159    }
5160    return true;
5161}
5162
5163// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5164// register value, and writes the result to the destination register.  It can optionally update the
5165// condition flags based on the result.
5166bool
5167EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5168{
5169#if 0
5170    // ARM pseudo code...
5171    if ConditionPassed() then
5172        EncodingSpecificOperations();
5173        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5174        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5175        if d == 15 then         // Can only occur for ARM encoding
5176            ALUWritePC(result); // setflags is always FALSE here
5177        else
5178            R[d] = result;
5179            if setflags then
5180                APSR.N = result<31>;
5181                APSR.Z = IsZeroBit(result);
5182                APSR.C = carry;
5183                APSR.V = overflow;
5184#endif
5185
5186    bool success = false;
5187
5188    if (ConditionPassed(opcode))
5189    {
5190        uint32_t Rd, Rn, Rm;
5191        ARM_ShifterType shift_t;
5192        uint32_t shift_n; // the shift applied to the value read from Rm
5193        bool setflags;
5194        switch (encoding)
5195        {
5196        case eEncodingT1:
5197            Rd = Rn = Bits32(opcode, 2, 0);
5198            Rm = Bits32(opcode, 5, 3);
5199            setflags = !InITBlock();
5200            shift_t = SRType_LSL;
5201            shift_n = 0;
5202            break;
5203        case eEncodingT2:
5204            Rd = Bits32(opcode, 11, 8);
5205            Rn = Bits32(opcode, 19, 16);
5206            Rm = Bits32(opcode, 3, 0);
5207            setflags = BitIsSet(opcode, 20);
5208            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5209            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5210                return false;
5211            break;
5212        case eEncodingA1:
5213            Rd = Bits32(opcode, 15, 12);
5214            Rn = Bits32(opcode, 19, 16);
5215            Rm = Bits32(opcode, 3, 0);
5216            setflags = BitIsSet(opcode, 20);
5217            shift_n = DecodeImmShiftARM(opcode, shift_t);
5218
5219            if (Rd == 15 && setflags)
5220                return EmulateSUBSPcLrEtc (opcode, encoding);
5221            break;
5222        default:
5223            return false;
5224        }
5225
5226        // Read the first operand.
5227        int32_t val1 = ReadCoreReg(Rn, &success);
5228        if (!success)
5229            return false;
5230
5231        // Read the second operand.
5232        int32_t val2 = ReadCoreReg(Rm, &success);
5233        if (!success)
5234            return false;
5235
5236        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
5237        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5238
5239        EmulateInstruction::Context context;
5240        context.type = EmulateInstruction::eContextImmediate;
5241        context.SetNoArgs ();
5242
5243        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5244            return false;
5245    }
5246    return true;
5247}
5248
5249// This instruction adds an immediate value to the PC value to form a PC-relative address,
5250// and writes the result to the destination register.
5251bool
5252EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5253{
5254#if 0
5255    // ARM pseudo code...
5256    if ConditionPassed() then
5257        EncodingSpecificOperations();
5258        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5259        if d == 15 then         // Can only occur for ARM encodings
5260            ALUWritePC(result);
5261        else
5262            R[d] = result;
5263#endif
5264
5265    bool success = false;
5266
5267    if (ConditionPassed(opcode))
5268    {
5269        uint32_t Rd;
5270        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5271        bool add;
5272        switch (encoding)
5273        {
5274        case eEncodingT1:
5275            Rd = Bits32(opcode, 10, 8);
5276            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5277            break;
5278        case eEncodingT2:
5279        case eEncodingT3:
5280            Rd = Bits32(opcode, 11, 8);
5281            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5282            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5283            if (BadReg(Rd))
5284                return false;
5285            break;
5286        case eEncodingA1:
5287        case eEncodingA2:
5288            Rd = Bits32(opcode, 15, 12);
5289            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5290            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5291            break;
5292        default:
5293            return false;
5294        }
5295
5296        // Read the PC value.
5297        uint32_t pc = ReadCoreReg(PC_REG, &success);
5298        if (!success)
5299            return false;
5300
5301        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5302
5303        EmulateInstruction::Context context;
5304        context.type = EmulateInstruction::eContextImmediate;
5305        context.SetNoArgs ();
5306
5307        if (!WriteCoreReg(context, result, Rd))
5308            return false;
5309    }
5310    return true;
5311}
5312
5313// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5314// to the destination register.  It can optionally update the condition flags based on the result.
5315bool
5316EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5317{
5318#if 0
5319    // ARM pseudo code...
5320    if ConditionPassed() then
5321        EncodingSpecificOperations();
5322        result = R[n] AND imm32;
5323        if d == 15 then         // Can only occur for ARM encoding
5324            ALUWritePC(result); // setflags is always FALSE here
5325        else
5326            R[d] = result;
5327            if setflags then
5328                APSR.N = result<31>;
5329                APSR.Z = IsZeroBit(result);
5330                APSR.C = carry;
5331                // APSR.V unchanged
5332#endif
5333
5334    bool success = false;
5335
5336    if (ConditionPassed(opcode))
5337    {
5338        uint32_t Rd, Rn;
5339        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5340        bool setflags;
5341        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5342        switch (encoding)
5343        {
5344        case eEncodingT1:
5345            Rd = Bits32(opcode, 11, 8);
5346            Rn = Bits32(opcode, 19, 16);
5347            setflags = BitIsSet(opcode, 20);
5348            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5349            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5350            if (Rd == 15 && setflags)
5351                return EmulateTSTImm(opcode, eEncodingT1);
5352            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5353                return false;
5354            break;
5355        case eEncodingA1:
5356            Rd = Bits32(opcode, 15, 12);
5357            Rn = Bits32(opcode, 19, 16);
5358            setflags = BitIsSet(opcode, 20);
5359            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5360
5361            if (Rd == 15 && setflags)
5362                return EmulateSUBSPcLrEtc (opcode, encoding);
5363            break;
5364        default:
5365            return false;
5366        }
5367
5368        // Read the first operand.
5369        uint32_t val1 = ReadCoreReg(Rn, &success);
5370        if (!success)
5371            return false;
5372
5373        uint32_t result = val1 & imm32;
5374
5375        EmulateInstruction::Context context;
5376        context.type = EmulateInstruction::eContextImmediate;
5377        context.SetNoArgs ();
5378
5379        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5380            return false;
5381    }
5382    return true;
5383}
5384
5385// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5386// and writes the result to the destination register.  It can optionally update the condition flags
5387// based on the result.
5388bool
5389EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5390{
5391#if 0
5392    // ARM pseudo code...
5393    if ConditionPassed() then
5394        EncodingSpecificOperations();
5395        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5396        result = R[n] AND shifted;
5397        if d == 15 then         // Can only occur for ARM encoding
5398            ALUWritePC(result); // setflags is always FALSE here
5399        else
5400            R[d] = result;
5401            if setflags then
5402                APSR.N = result<31>;
5403                APSR.Z = IsZeroBit(result);
5404                APSR.C = carry;
5405                // APSR.V unchanged
5406#endif
5407
5408    bool success = false;
5409
5410    if (ConditionPassed(opcode))
5411    {
5412        uint32_t Rd, Rn, Rm;
5413        ARM_ShifterType shift_t;
5414        uint32_t shift_n; // the shift applied to the value read from Rm
5415        bool setflags;
5416        uint32_t carry;
5417        switch (encoding)
5418        {
5419        case eEncodingT1:
5420            Rd = Rn = Bits32(opcode, 2, 0);
5421            Rm = Bits32(opcode, 5, 3);
5422            setflags = !InITBlock();
5423            shift_t = SRType_LSL;
5424            shift_n = 0;
5425            break;
5426        case eEncodingT2:
5427            Rd = Bits32(opcode, 11, 8);
5428            Rn = Bits32(opcode, 19, 16);
5429            Rm = Bits32(opcode, 3, 0);
5430            setflags = BitIsSet(opcode, 20);
5431            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5432            // if Rd == '1111' && S == '1' then SEE TST (register);
5433            if (Rd == 15 && setflags)
5434                return EmulateTSTReg(opcode, eEncodingT2);
5435            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5436                return false;
5437            break;
5438        case eEncodingA1:
5439            Rd = Bits32(opcode, 15, 12);
5440            Rn = Bits32(opcode, 19, 16);
5441            Rm = Bits32(opcode, 3, 0);
5442            setflags = BitIsSet(opcode, 20);
5443            shift_n = DecodeImmShiftARM(opcode, shift_t);
5444
5445            if (Rd == 15 && setflags)
5446                return EmulateSUBSPcLrEtc (opcode, encoding);
5447            break;
5448        default:
5449            return false;
5450        }
5451
5452        // Read the first operand.
5453        uint32_t val1 = ReadCoreReg(Rn, &success);
5454        if (!success)
5455            return false;
5456
5457        // Read the second operand.
5458        uint32_t val2 = ReadCoreReg(Rm, &success);
5459        if (!success)
5460            return false;
5461
5462        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5463        uint32_t result = val1 & shifted;
5464
5465        EmulateInstruction::Context context;
5466        context.type = EmulateInstruction::eContextImmediate;
5467        context.SetNoArgs ();
5468
5469        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5470            return false;
5471    }
5472    return true;
5473}
5474
5475// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5476// immediate value, and writes the result to the destination register.  It can optionally update the
5477// condition flags based on the result.
5478bool
5479EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5480{
5481#if 0
5482    // ARM pseudo code...
5483    if ConditionPassed() then
5484        EncodingSpecificOperations();
5485        result = R[n] AND NOT(imm32);
5486        if d == 15 then         // Can only occur for ARM encoding
5487            ALUWritePC(result); // setflags is always FALSE here
5488        else
5489            R[d] = result;
5490            if setflags then
5491                APSR.N = result<31>;
5492                APSR.Z = IsZeroBit(result);
5493                APSR.C = carry;
5494                // APSR.V unchanged
5495#endif
5496
5497    bool success = false;
5498
5499    if (ConditionPassed(opcode))
5500    {
5501        uint32_t Rd, Rn;
5502        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5503        bool setflags;
5504        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5505        switch (encoding)
5506        {
5507        case eEncodingT1:
5508            Rd = Bits32(opcode, 11, 8);
5509            Rn = Bits32(opcode, 19, 16);
5510            setflags = BitIsSet(opcode, 20);
5511            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5512            if (BadReg(Rd) || BadReg(Rn))
5513                return false;
5514            break;
5515        case eEncodingA1:
5516            Rd = Bits32(opcode, 15, 12);
5517            Rn = Bits32(opcode, 19, 16);
5518            setflags = BitIsSet(opcode, 20);
5519            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5520
5521            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5522            if (Rd == 15 && setflags)
5523                return EmulateSUBSPcLrEtc (opcode, encoding);
5524            break;
5525        default:
5526            return false;
5527        }
5528
5529        // Read the first operand.
5530        uint32_t val1 = ReadCoreReg(Rn, &success);
5531        if (!success)
5532            return false;
5533
5534        uint32_t result = val1 & ~imm32;
5535
5536        EmulateInstruction::Context context;
5537        context.type = EmulateInstruction::eContextImmediate;
5538        context.SetNoArgs ();
5539
5540        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5541            return false;
5542    }
5543    return true;
5544}
5545
5546// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5547// optionally-shifted register value, and writes the result to the destination register.
5548// It can optionally update the condition flags based on the result.
5549bool
5550EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5551{
5552#if 0
5553    // ARM pseudo code...
5554    if ConditionPassed() then
5555        EncodingSpecificOperations();
5556        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5557        result = R[n] AND NOT(shifted);
5558        if d == 15 then         // Can only occur for ARM encoding
5559            ALUWritePC(result); // setflags is always FALSE here
5560        else
5561            R[d] = result;
5562            if setflags then
5563                APSR.N = result<31>;
5564                APSR.Z = IsZeroBit(result);
5565                APSR.C = carry;
5566                // APSR.V unchanged
5567#endif
5568
5569    bool success = false;
5570
5571    if (ConditionPassed(opcode))
5572    {
5573        uint32_t Rd, Rn, Rm;
5574        ARM_ShifterType shift_t;
5575        uint32_t shift_n; // the shift applied to the value read from Rm
5576        bool setflags;
5577        uint32_t carry;
5578        switch (encoding)
5579        {
5580        case eEncodingT1:
5581            Rd = Rn = Bits32(opcode, 2, 0);
5582            Rm = Bits32(opcode, 5, 3);
5583            setflags = !InITBlock();
5584            shift_t = SRType_LSL;
5585            shift_n = 0;
5586            break;
5587        case eEncodingT2:
5588            Rd = Bits32(opcode, 11, 8);
5589            Rn = Bits32(opcode, 19, 16);
5590            Rm = Bits32(opcode, 3, 0);
5591            setflags = BitIsSet(opcode, 20);
5592            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5593            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5594                return false;
5595            break;
5596        case eEncodingA1:
5597            Rd = Bits32(opcode, 15, 12);
5598            Rn = Bits32(opcode, 19, 16);
5599            Rm = Bits32(opcode, 3, 0);
5600            setflags = BitIsSet(opcode, 20);
5601            shift_n = DecodeImmShiftARM(opcode, shift_t);
5602
5603            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5604            if (Rd == 15 && setflags)
5605                return EmulateSUBSPcLrEtc (opcode, encoding);
5606            break;
5607        default:
5608            return false;
5609        }
5610
5611        // Read the first operand.
5612        uint32_t val1 = ReadCoreReg(Rn, &success);
5613        if (!success)
5614            return false;
5615
5616        // Read the second operand.
5617        uint32_t val2 = ReadCoreReg(Rm, &success);
5618        if (!success)
5619            return false;
5620
5621        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5622        uint32_t result = val1 & ~shifted;
5623
5624        EmulateInstruction::Context context;
5625        context.type = EmulateInstruction::eContextImmediate;
5626        context.SetNoArgs ();
5627
5628        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5629            return false;
5630    }
5631    return true;
5632}
5633
5634// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5635// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5636bool
5637EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5638{
5639#if 0
5640    if ConditionPassed() then
5641        EncodingSpecificOperations();
5642        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5643        address = if index then offset_addr else R[n];
5644        data = MemU[address,4];
5645        if wback then R[n] = offset_addr;
5646        if t == 15 then
5647            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5648        elsif UnalignedSupport() || address<1:0> = '00' then
5649            R[t] = data;
5650        else // Can only apply before ARMv7
5651            R[t] = ROR(data, 8*UInt(address<1:0>));
5652#endif
5653
5654    bool success = false;
5655
5656    if (ConditionPassed(opcode))
5657    {
5658        const uint32_t addr_byte_size = GetAddressByteSize();
5659
5660        uint32_t t;
5661        uint32_t n;
5662        uint32_t imm32;
5663        bool index;
5664        bool add;
5665        bool wback;
5666
5667        switch (encoding)
5668        {
5669            case eEncodingA1:
5670                // if Rn == '1111' then SEE LDR (literal);
5671                // if P == '0' && W == '1' then SEE LDRT;
5672                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5673                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5674                t = Bits32 (opcode, 15, 12);
5675                n = Bits32 (opcode, 19, 16);
5676                imm32 = Bits32 (opcode, 11, 0);
5677
5678                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5679                index = BitIsSet (opcode, 24);
5680                add = BitIsSet (opcode, 23);
5681                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5682
5683                // if wback && n == t then UNPREDICTABLE;
5684                if (wback && (n == t))
5685                    return false;
5686
5687                break;
5688
5689            default:
5690                return false;
5691        }
5692
5693        addr_t address;
5694        addr_t offset_addr;
5695        addr_t base_address = ReadCoreReg (n, &success);
5696        if (!success)
5697            return false;
5698
5699        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5700        if (add)
5701            offset_addr = base_address + imm32;
5702        else
5703            offset_addr = base_address - imm32;
5704
5705        // address = if index then offset_addr else R[n];
5706        if (index)
5707            address = offset_addr;
5708        else
5709            address = base_address;
5710
5711        // data = MemU[address,4];
5712
5713        Register base_reg;
5714        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5715
5716        EmulateInstruction::Context context;
5717        context.type = eContextRegisterLoad;
5718        context.SetRegisterPlusOffset (base_reg, address - base_address);
5719
5720        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5721        if (!success)
5722            return false;
5723
5724        // if wback then R[n] = offset_addr;
5725        if (wback)
5726        {
5727            context.type = eContextAdjustBaseRegister;
5728            context.SetAddress (offset_addr);
5729            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5730                return false;
5731        }
5732
5733        // if t == 15 then
5734        if (t == 15)
5735        {
5736            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5737            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5738            {
5739                // LoadWritePC (data);
5740                context.type = eContextRegisterLoad;
5741                context.SetRegisterPlusOffset (base_reg, address - base_address);
5742                LoadWritePC (context, data);
5743            }
5744            else
5745                  return false;
5746        }
5747        // elsif UnalignedSupport() || address<1:0> = '00' then
5748        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5749        {
5750            // R[t] = data;
5751            context.type = eContextRegisterLoad;
5752            context.SetRegisterPlusOffset (base_reg, address - base_address);
5753            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5754                return false;
5755        }
5756        // else // Can only apply before ARMv7
5757        else
5758        {
5759            // R[t] = ROR(data, 8*UInt(address<1:0>));
5760            data = ROR (data, Bits32 (address, 1, 0));
5761            context.type = eContextRegisterLoad;
5762            context.SetImmediate (data);
5763            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5764                return false;
5765        }
5766
5767    }
5768    return true;
5769}
5770
5771// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5772// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5773bool
5774EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5775{
5776#if 0
5777    if ConditionPassed() then
5778        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5779        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5780        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5781        address = if index then offset_addr else R[n];
5782        data = MemU[address,4];
5783        if wback then R[n] = offset_addr;
5784        if t == 15 then
5785            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5786        elsif UnalignedSupport() || address<1:0> = '00' then
5787            R[t] = data;
5788        else // Can only apply before ARMv7
5789            if CurrentInstrSet() == InstrSet_ARM then
5790                R[t] = ROR(data, 8*UInt(address<1:0>));
5791            else
5792                R[t] = bits(32) UNKNOWN;
5793#endif
5794
5795    bool success = false;
5796
5797    if (ConditionPassed(opcode))
5798    {
5799        const uint32_t addr_byte_size = GetAddressByteSize();
5800
5801        uint32_t t;
5802        uint32_t n;
5803        uint32_t m;
5804        bool index;
5805        bool add;
5806        bool wback;
5807        ARM_ShifterType shift_t;
5808        uint32_t shift_n;
5809
5810        switch (encoding)
5811        {
5812            case eEncodingT1:
5813                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5814                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5815                t = Bits32 (opcode, 2, 0);
5816                n = Bits32 (opcode, 5, 3);
5817                m = Bits32 (opcode, 8, 6);
5818
5819                // index = TRUE; add = TRUE; wback = FALSE;
5820                index = true;
5821                add = true;
5822                wback = false;
5823
5824                // (shift_t, shift_n) = (SRType_LSL, 0);
5825                shift_t = SRType_LSL;
5826                shift_n = 0;
5827
5828                break;
5829
5830            case eEncodingT2:
5831                // if Rn == '1111' then SEE LDR (literal);
5832                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5833                t = Bits32 (opcode, 15, 12);
5834                n = Bits32 (opcode, 19, 16);
5835                m = Bits32 (opcode, 3, 0);
5836
5837                // index = TRUE; add = TRUE; wback = FALSE;
5838                index = true;
5839                add = true;
5840                wback = false;
5841
5842                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5843                shift_t = SRType_LSL;
5844                shift_n = Bits32 (opcode, 5, 4);
5845
5846                // if BadReg(m) then UNPREDICTABLE;
5847                if (BadReg (m))
5848                    return false;
5849
5850                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5851                if ((t == 15) && InITBlock() && !LastInITBlock())
5852                    return false;
5853
5854                break;
5855
5856            case eEncodingA1:
5857            {
5858                // if P == '0' && W == '1' then SEE LDRT;
5859                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5860                t = Bits32 (opcode, 15, 12);
5861                n = Bits32 (opcode, 19, 16);
5862                m = Bits32 (opcode, 3, 0);
5863
5864                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5865                index = BitIsSet (opcode, 24);
5866                add = BitIsSet (opcode, 23);
5867                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5868
5869                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5870                uint32_t type = Bits32 (opcode, 6, 5);
5871                uint32_t imm5 = Bits32 (opcode, 11, 7);
5872                shift_n = DecodeImmShift (type, imm5, shift_t);
5873
5874                // if m == 15 then UNPREDICTABLE;
5875                if (m == 15)
5876                    return false;
5877
5878                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5879                if (wback && ((n == 15) || (n == t)))
5880                    return false;
5881            }
5882                break;
5883
5884
5885            default:
5886                return false;
5887        }
5888
5889        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5890        if (!success)
5891            return false;
5892
5893        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5894        if (!success)
5895            return false;
5896
5897        addr_t offset_addr;
5898        addr_t address;
5899
5900        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
5901        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C));
5902
5903        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5904        if (add)
5905            offset_addr = Rn + offset;
5906        else
5907            offset_addr = Rn - offset;
5908
5909        // address = if index then offset_addr else R[n];
5910            if (index)
5911                address = offset_addr;
5912            else
5913                address = Rn;
5914
5915        // data = MemU[address,4];
5916        Register base_reg;
5917        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5918
5919        EmulateInstruction::Context context;
5920        context.type = eContextRegisterLoad;
5921        context.SetRegisterPlusOffset (base_reg, address - Rn);
5922
5923        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5924        if (!success)
5925            return false;
5926
5927        // if wback then R[n] = offset_addr;
5928        if (wback)
5929        {
5930            context.type = eContextAdjustBaseRegister;
5931            context.SetAddress (offset_addr);
5932            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5933                return false;
5934        }
5935
5936        // if t == 15 then
5937        if (t == 15)
5938        {
5939            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5940            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5941            {
5942                context.type = eContextRegisterLoad;
5943                context.SetRegisterPlusOffset (base_reg, address - Rn);
5944                LoadWritePC (context, data);
5945            }
5946            else
5947                return false;
5948        }
5949        // elsif UnalignedSupport() || address<1:0> = '00' then
5950        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5951        {
5952            // R[t] = data;
5953            context.type = eContextRegisterLoad;
5954            context.SetRegisterPlusOffset (base_reg, address - Rn);
5955            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5956                return false;
5957        }
5958        else // Can only apply before ARMv7
5959        {
5960            // if CurrentInstrSet() == InstrSet_ARM then
5961            if (CurrentInstrSet () == eModeARM)
5962            {
5963                // R[t] = ROR(data, 8*UInt(address<1:0>));
5964                data = ROR (data, Bits32 (address, 1, 0));
5965                context.type = eContextRegisterLoad;
5966                context.SetImmediate (data);
5967                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5968                    return false;
5969            }
5970            else
5971            {
5972                // R[t] = bits(32) UNKNOWN;
5973                WriteBits32Unknown (t);
5974            }
5975        }
5976    }
5977    return true;
5978}
5979
5980// LDRB (immediate, Thumb)
5981bool
5982EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
5983{
5984#if 0
5985    if ConditionPassed() then
5986        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5987        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5988        address = if index then offset_addr else R[n];
5989        R[t] = ZeroExtend(MemU[address,1], 32);
5990        if wback then R[n] = offset_addr;
5991#endif
5992
5993    bool success = false;
5994
5995    if (ConditionPassed(opcode))
5996    {
5997        uint32_t t;
5998        uint32_t n;
5999        uint32_t imm32;
6000        bool index;
6001        bool add;
6002        bool wback;
6003
6004        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6005        switch (encoding)
6006        {
6007            case eEncodingT1:
6008                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6009                t = Bits32 (opcode, 2, 0);
6010                n = Bits32 (opcode, 5, 3);
6011                imm32 = Bits32 (opcode, 10, 6);
6012
6013                // index = TRUE; add = TRUE; wback = FALSE;
6014                index = true;
6015                add = true;
6016                wback= false;
6017
6018                break;
6019
6020            case eEncodingT2:
6021                // if Rt == '1111' then SEE PLD;
6022                // if Rn == '1111' then SEE LDRB (literal);
6023                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6024                t = Bits32 (opcode, 15, 12);
6025                n = Bits32 (opcode, 19, 16);
6026                imm32 = Bits32 (opcode, 11, 0);
6027
6028                // index = TRUE; add = TRUE; wback = FALSE;
6029                index = true;
6030                add = true;
6031                wback = false;
6032
6033                // if t == 13 then UNPREDICTABLE;
6034                if (t == 13)
6035                    return false;
6036
6037                break;
6038
6039            case eEncodingT3:
6040                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6041                // if Rn == '1111' then SEE LDRB (literal);
6042                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6043                // if P == '0' && W == '0' then UNDEFINED;
6044                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6045                    return false;
6046
6047                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6048                t = Bits32 (opcode, 15, 12);
6049                n = Bits32 (opcode, 19, 16);
6050                imm32 = Bits32 (opcode, 7, 0);
6051
6052                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6053                index = BitIsSet (opcode, 10);
6054                add = BitIsSet (opcode, 9);
6055                wback = BitIsSet (opcode, 8);
6056
6057                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6058                if (BadReg (t) || (wback && (n == t)))
6059                    return false;
6060
6061                break;
6062
6063            default:
6064                return false;
6065        }
6066
6067        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6068        if (!success)
6069            return false;
6070
6071        addr_t address;
6072        addr_t offset_addr;
6073
6074        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6075        if (add)
6076            offset_addr = Rn + imm32;
6077        else
6078            offset_addr = Rn - imm32;
6079
6080        // address = if index then offset_addr else R[n];
6081        if (index)
6082            address = offset_addr;
6083        else
6084            address = Rn;
6085
6086        // R[t] = ZeroExtend(MemU[address,1], 32);
6087        Register base_reg;
6088        Register data_reg;
6089        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6090        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
6091
6092        EmulateInstruction::Context context;
6093        context.type = eContextRegisterLoad;
6094        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6095
6096        uint64_t data = MemURead (context, address, 1, 0, &success);
6097        if (!success)
6098            return false;
6099
6100        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6101            return false;
6102
6103        // if wback then R[n] = offset_addr;
6104        if (wback)
6105        {
6106            context.type = eContextAdjustBaseRegister;
6107            context.SetAddress (offset_addr);
6108            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6109                return false;
6110        }
6111    }
6112    return true;
6113}
6114
6115// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6116// zero-extends it to form a 32-bit word and writes it to a register.
6117bool
6118EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6119{
6120#if 0
6121    if ConditionPassed() then
6122        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6123        base = Align(PC,4);
6124        address = if add then (base + imm32) else (base - imm32);
6125        R[t] = ZeroExtend(MemU[address,1], 32);
6126#endif
6127
6128    bool success = false;
6129
6130    if (ConditionPassed(opcode))
6131    {
6132        uint32_t t;
6133        uint32_t imm32;
6134        bool add;
6135        switch (encoding)
6136        {
6137            case eEncodingT1:
6138                // if Rt == '1111' then SEE PLD;
6139                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6140                t = Bits32 (opcode, 15, 12);
6141                imm32 = Bits32 (opcode, 11, 0);
6142                add = BitIsSet (opcode, 23);
6143
6144                // if t == 13 then UNPREDICTABLE;
6145                if (t == 13)
6146                    return false;
6147
6148                break;
6149
6150            case eEncodingA1:
6151                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6152                t = Bits32 (opcode, 15, 12);
6153                imm32 = Bits32 (opcode, 11, 0);
6154                add = BitIsSet (opcode, 23);
6155
6156                // if t == 15 then UNPREDICTABLE;
6157                if (t == 15)
6158                    return false;
6159                break;
6160
6161            default:
6162                return false;
6163        }
6164
6165        // base = Align(PC,4);
6166        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6167        if (!success)
6168            return false;
6169
6170        uint32_t base = AlignPC (pc_val);
6171
6172        addr_t address;
6173        // address = if add then (base + imm32) else (base - imm32);
6174        if (add)
6175            address = base + imm32;
6176        else
6177            address = base - imm32;
6178
6179        // R[t] = ZeroExtend(MemU[address,1], 32);
6180        EmulateInstruction::Context context;
6181        context.type = eContextRelativeBranchImmediate;
6182        context.SetImmediate (address - base);
6183
6184        uint64_t data = MemURead (context, address, 1, 0, &success);
6185        if (!success)
6186            return false;
6187
6188        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6189            return false;
6190    }
6191    return true;
6192}
6193
6194// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6195// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6196// optionally be shifted.
6197bool
6198EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6199{
6200#if 0
6201    if ConditionPassed() then
6202        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6203        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6204        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6205        address = if index then offset_addr else R[n];
6206        R[t] = ZeroExtend(MemU[address,1],32);
6207        if wback then R[n] = offset_addr;
6208#endif
6209
6210    bool success = false;
6211
6212    if (ConditionPassed(opcode))
6213    {
6214        uint32_t t;
6215        uint32_t n;
6216        uint32_t m;
6217        bool index;
6218        bool add;
6219        bool wback;
6220        ARM_ShifterType shift_t;
6221        uint32_t shift_n;
6222
6223        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6224        switch (encoding)
6225        {
6226            case eEncodingT1:
6227                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6228                t = Bits32 (opcode, 2, 0);
6229                n = Bits32 (opcode, 5, 3);
6230                m = Bits32 (opcode, 8, 6);
6231
6232                // index = TRUE; add = TRUE; wback = FALSE;
6233                index = true;
6234                add = true;
6235                wback = false;
6236
6237                // (shift_t, shift_n) = (SRType_LSL, 0);
6238                shift_t = SRType_LSL;
6239                shift_n = 0;
6240                break;
6241
6242            case eEncodingT2:
6243                // if Rt == '1111' then SEE PLD;
6244                // if Rn == '1111' then SEE LDRB (literal);
6245                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6246                t = Bits32 (opcode, 15, 12);
6247                n = Bits32 (opcode, 19, 16);
6248                m = Bits32 (opcode, 3, 0);
6249
6250                // index = TRUE; add = TRUE; wback = FALSE;
6251                index = true;
6252                add = true;
6253                wback = false;
6254
6255                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6256                shift_t = SRType_LSL;
6257                shift_n = Bits32 (opcode, 5, 4);
6258
6259                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6260                if ((t == 13) || BadReg (m))
6261                    return false;
6262                break;
6263
6264            case eEncodingA1:
6265            {
6266                // if P == '0' && W == '1' then SEE LDRBT;
6267                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6268                t = Bits32 (opcode, 15, 12);
6269                n = Bits32 (opcode, 19, 16);
6270                m = Bits32 (opcode, 3, 0);
6271
6272                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6273                index = BitIsSet (opcode, 24);
6274                add = BitIsSet (opcode, 23);
6275                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6276
6277                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6278                uint32_t type = Bits32 (opcode, 6, 5);
6279                uint32_t imm5 = Bits32 (opcode, 11, 7);
6280                shift_n = DecodeImmShift (type, imm5, shift_t);
6281
6282                // if t == 15 || m == 15 then UNPREDICTABLE;
6283                if ((t == 15) || (m == 15))
6284                    return false;
6285
6286                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6287                if (wback && ((n == 15) || (n == t)))
6288                    return false;
6289            }
6290                break;
6291
6292            default:
6293                return false;
6294        }
6295
6296        addr_t offset_addr;
6297        addr_t address;
6298
6299        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6300        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6301        if (!success)
6302            return false;
6303
6304        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6305
6306        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6307        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6308        if (!success)
6309            return false;
6310
6311        if (add)
6312            offset_addr = Rn + offset;
6313        else
6314            offset_addr = Rn - offset;
6315
6316        // address = if index then offset_addr else R[n];
6317        if (index)
6318            address = offset_addr;
6319        else
6320            address = Rn;
6321
6322        // R[t] = ZeroExtend(MemU[address,1],32);
6323        Register base_reg;
6324        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6325
6326        EmulateInstruction::Context context;
6327        context.type = eContextRegisterLoad;
6328        context.SetRegisterPlusOffset (base_reg, address - Rn);
6329
6330        uint64_t data = MemURead (context, address, 1, 0, &success);
6331        if (!success)
6332            return false;
6333
6334        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6335            return false;
6336
6337        // if wback then R[n] = offset_addr;
6338        if (wback)
6339        {
6340            context.type = eContextAdjustBaseRegister;
6341            context.SetAddress (offset_addr);
6342            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6343                return false;
6344        }
6345    }
6346    return true;
6347}
6348
6349// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6350// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6351// post-indexed, or pre-indexed addressing.
6352bool
6353EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6354{
6355#if 0
6356    if ConditionPassed() then
6357        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6358        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6359        address = if index then offset_addr else R[n];
6360        data = MemU[address,2];
6361        if wback then R[n] = offset_addr;
6362        if UnalignedSupport() || address<0> = '0' then
6363            R[t] = ZeroExtend(data, 32);
6364        else // Can only apply before ARMv7
6365            R[t] = bits(32) UNKNOWN;
6366#endif
6367
6368
6369    bool success = false;
6370
6371    if (ConditionPassed(opcode))
6372    {
6373        uint32_t t;
6374        uint32_t n;
6375        uint32_t imm32;
6376        bool index;
6377        bool add;
6378        bool wback;
6379
6380        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6381        switch (encoding)
6382        {
6383            case eEncodingT1:
6384                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6385                t = Bits32 (opcode, 2, 0);
6386                n = Bits32 (opcode, 5, 3);
6387                imm32 = Bits32 (opcode, 10, 6) << 1;
6388
6389                // index = TRUE; add = TRUE; wback = FALSE;
6390                index = true;
6391                add = true;
6392                wback = false;
6393
6394                break;
6395
6396            case eEncodingT2:
6397                // if Rt == '1111' then SEE "Unallocated memory hints";
6398                // if Rn == '1111' then SEE LDRH (literal);
6399                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6400                t = Bits32 (opcode, 15, 12);
6401                n = Bits32 (opcode, 19, 16);
6402                imm32 = Bits32 (opcode, 11, 0);
6403
6404                // index = TRUE; add = TRUE; wback = FALSE;
6405                index = true;
6406                add = true;
6407                wback = false;
6408
6409                // if t == 13 then UNPREDICTABLE;
6410                if (t == 13)
6411                    return false;
6412                break;
6413
6414            case eEncodingT3:
6415                // if Rn == '1111' then SEE LDRH (literal);
6416                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6417                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6418                // if P == '0' && W == '0' then UNDEFINED;
6419                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6420                    return false;
6421
6422                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6423                t = Bits32 (opcode, 15, 12);
6424                n = Bits32 (opcode, 19, 16);
6425                imm32 = Bits32 (opcode, 7, 0);
6426
6427                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6428                index = BitIsSet (opcode, 10);
6429                add = BitIsSet (opcode, 9);
6430                wback = BitIsSet (opcode, 8);
6431
6432                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6433                if (BadReg (t) || (wback && (n == t)))
6434                    return false;
6435                break;
6436
6437            default:
6438                return false;
6439        }
6440
6441        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6442        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6443        if (!success)
6444            return false;
6445
6446        addr_t offset_addr;
6447        addr_t address;
6448
6449        if (add)
6450            offset_addr = Rn + imm32;
6451        else
6452            offset_addr = Rn - imm32;
6453
6454        // address = if index then offset_addr else R[n];
6455        if (index)
6456            address = offset_addr;
6457        else
6458            address = Rn;
6459
6460        // data = MemU[address,2];
6461        Register base_reg;
6462        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6463
6464        EmulateInstruction::Context context;
6465        context.type = eContextRegisterLoad;
6466        context.SetRegisterPlusOffset (base_reg, address - Rn);
6467
6468        uint64_t data = MemURead (context, address, 2, 0, &success);
6469        if (!success)
6470            return false;
6471
6472        // if wback then R[n] = offset_addr;
6473        if (wback)
6474        {
6475            context.type = eContextAdjustBaseRegister;
6476            context.SetAddress (offset_addr);
6477            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6478                return false;
6479        }
6480
6481        // if UnalignedSupport() || address<0> = '0' then
6482        if (UnalignedSupport () || BitIsClear (address, 0))
6483        {
6484            // R[t] = ZeroExtend(data, 32);
6485            context.type = eContextRegisterLoad;
6486            context.SetRegisterPlusOffset (base_reg, address - Rn);
6487            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6488                return false;
6489        }
6490        else // Can only apply before ARMv7
6491        {
6492            // R[t] = bits(32) UNKNOWN;
6493            WriteBits32Unknown (t);
6494        }
6495    }
6496    return true;
6497}
6498
6499// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6500// zero-extends it to form a 32-bit word, and writes it to a register.
6501bool
6502EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6503{
6504#if 0
6505    if ConditionPassed() then
6506        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6507        base = Align(PC,4);
6508        address = if add then (base + imm32) else (base - imm32);
6509        data = MemU[address,2];
6510        if UnalignedSupport() || address<0> = '0' then
6511            R[t] = ZeroExtend(data, 32);
6512        else // Can only apply before ARMv7
6513            R[t] = bits(32) UNKNOWN;
6514#endif
6515
6516    bool success = false;
6517
6518    if (ConditionPassed(opcode))
6519    {
6520        uint32_t t;
6521        uint32_t imm32;
6522        bool add;
6523
6524        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6525        switch (encoding)
6526        {
6527            case eEncodingT1:
6528                // if Rt == '1111' then SEE "Unallocated memory hints";
6529                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6530                t = Bits32 (opcode, 15, 12);
6531                imm32 = Bits32 (opcode, 11, 0);
6532                add = BitIsSet (opcode, 23);
6533
6534                // if t == 13 then UNPREDICTABLE;
6535                if (t == 13)
6536                    return false;
6537
6538                break;
6539
6540            case eEncodingA1:
6541            {
6542                uint32_t imm4H = Bits32 (opcode, 11, 8);
6543                uint32_t imm4L = Bits32 (opcode, 3, 0);
6544
6545                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6546                t = Bits32 (opcode, 15, 12);
6547                imm32 = (imm4H << 4) | imm4L;
6548                add = BitIsSet (opcode, 23);
6549
6550                // if t == 15 then UNPREDICTABLE;
6551                if (t == 15)
6552                    return false;
6553                break;
6554            }
6555
6556            default:
6557                return false;
6558        }
6559
6560        // base = Align(PC,4);
6561        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6562        if (!success)
6563            return false;
6564
6565        addr_t base = AlignPC (pc_value);
6566        addr_t address;
6567
6568        // address = if add then (base + imm32) else (base - imm32);
6569        if (add)
6570            address = base + imm32;
6571        else
6572            address = base - imm32;
6573
6574        // data = MemU[address,2];
6575        Register base_reg;
6576        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
6577
6578        EmulateInstruction::Context context;
6579        context.type = eContextRegisterLoad;
6580        context.SetRegisterPlusOffset (base_reg, address - base);
6581
6582        uint64_t data = MemURead (context, address, 2, 0, &success);
6583        if (!success)
6584            return false;
6585
6586
6587        // if UnalignedSupport() || address<0> = '0' then
6588        if (UnalignedSupport () || BitIsClear (address, 0))
6589        {
6590            // R[t] = ZeroExtend(data, 32);
6591            context.type = eContextRegisterLoad;
6592            context.SetRegisterPlusOffset (base_reg, address - base);
6593            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6594                return false;
6595
6596        }
6597        else // Can only apply before ARMv7
6598        {
6599            // R[t] = bits(32) UNKNOWN;
6600            WriteBits32Unknown (t);
6601        }
6602    }
6603    return true;
6604}
6605
6606// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6607// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6608// be shifted left by 0, 1, 2, or 3 bits.
6609bool
6610EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6611{
6612#if 0
6613    if ConditionPassed() then
6614        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6615        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6616        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6617        address = if index then offset_addr else R[n];
6618        data = MemU[address,2];
6619        if wback then R[n] = offset_addr;
6620        if UnalignedSupport() || address<0> = '0' then
6621            R[t] = ZeroExtend(data, 32);
6622        else // Can only apply before ARMv7
6623            R[t] = bits(32) UNKNOWN;
6624#endif
6625
6626    bool success = false;
6627
6628    if (ConditionPassed(opcode))
6629    {
6630        uint32_t t;
6631        uint32_t n;
6632        uint32_t m;
6633        bool index;
6634        bool add;
6635        bool wback;
6636        ARM_ShifterType shift_t;
6637        uint32_t shift_n;
6638
6639        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6640        switch (encoding)
6641        {
6642            case eEncodingT1:
6643                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6644                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6645                t = Bits32 (opcode, 2, 0);
6646                n = Bits32 (opcode, 5, 3);
6647                m = Bits32 (opcode, 8, 6);
6648
6649                // index = TRUE; add = TRUE; wback = FALSE;
6650                index = true;
6651                add = true;
6652                wback = false;
6653
6654                // (shift_t, shift_n) = (SRType_LSL, 0);
6655                shift_t = SRType_LSL;
6656                shift_n = 0;
6657
6658                break;
6659
6660            case eEncodingT2:
6661                // if Rn == '1111' then SEE LDRH (literal);
6662                // if Rt == '1111' then SEE "Unallocated memory hints";
6663                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6664                t = Bits32 (opcode, 15, 12);
6665                n = Bits32 (opcode, 19, 16);
6666                m = Bits32 (opcode, 3, 0);
6667
6668                // index = TRUE; add = TRUE; wback = FALSE;
6669                index = true;
6670                add = true;
6671                wback = false;
6672
6673                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6674                shift_t = SRType_LSL;
6675                shift_n = Bits32 (opcode, 5, 4);
6676
6677                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6678                if ((t == 13) || BadReg (m))
6679                    return false;
6680                break;
6681
6682            case eEncodingA1:
6683                // if P == '0' && W == '1' then SEE LDRHT;
6684                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6685                t = Bits32 (opcode, 15, 12);
6686                n = Bits32 (opcode, 19, 16);
6687                m = Bits32 (opcode, 3, 0);
6688
6689                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6690                index = BitIsSet (opcode, 24);
6691                add = BitIsSet (opcode, 23);
6692                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6693
6694                // (shift_t, shift_n) = (SRType_LSL, 0);
6695                shift_t = SRType_LSL;
6696                shift_n = 0;
6697
6698                // if t == 15 || m == 15 then UNPREDICTABLE;
6699                if ((t == 15) || (m == 15))
6700                    return false;
6701
6702                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6703                if (wback && ((n == 15) || (n == t)))
6704                    return false;
6705
6706                break;
6707
6708            default:
6709                return false;
6710        }
6711
6712        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6713
6714        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6715        if (!success)
6716            return false;
6717
6718        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6719
6720        addr_t offset_addr;
6721        addr_t address;
6722
6723        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6724        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6725        if (!success)
6726            return false;
6727
6728        if (add)
6729            offset_addr = Rn + offset;
6730        else
6731            offset_addr = Rn - offset;
6732
6733        // address = if index then offset_addr else R[n];
6734        if (index)
6735            address = offset_addr;
6736        else
6737            address = Rn;
6738
6739        // data = MemU[address,2];
6740        Register base_reg;
6741        Register offset_reg;
6742        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6743        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
6744
6745        EmulateInstruction::Context context;
6746        context.type = eContextRegisterLoad;
6747        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6748        uint64_t data = MemURead (context, address, 2, 0, &success);
6749        if (!success)
6750            return false;
6751
6752        // if wback then R[n] = offset_addr;
6753        if (wback)
6754        {
6755            context.type = eContextAdjustBaseRegister;
6756            context.SetAddress (offset_addr);
6757            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6758                return false;
6759        }
6760
6761        // if UnalignedSupport() || address<0> = '0' then
6762        if (UnalignedSupport() || BitIsClear (address, 0))
6763        {
6764            // R[t] = ZeroExtend(data, 32);
6765            context.type = eContextRegisterLoad;
6766            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6767            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6768                return false;
6769        }
6770        else // Can only apply before ARMv7
6771        {
6772            // R[t] = bits(32) UNKNOWN;
6773            WriteBits32Unknown (t);
6774        }
6775    }
6776    return true;
6777}
6778
6779// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6780// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6781// or pre-indexed addressing.
6782bool
6783EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6784{
6785#if 0
6786    if ConditionPassed() then
6787        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6788        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6789        address = if index then offset_addr else R[n];
6790        R[t] = SignExtend(MemU[address,1], 32);
6791        if wback then R[n] = offset_addr;
6792#endif
6793
6794    bool success = false;
6795
6796    if (ConditionPassed(opcode))
6797    {
6798        uint32_t t;
6799        uint32_t n;
6800        uint32_t imm32;
6801        bool index;
6802        bool add;
6803        bool wback;
6804
6805        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6806        switch (encoding)
6807        {
6808            case eEncodingT1:
6809                // if Rt == '1111' then SEE PLI;
6810                // if Rn == '1111' then SEE LDRSB (literal);
6811                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6812                t = Bits32 (opcode, 15, 12);
6813                n = Bits32 (opcode, 19, 16);
6814                imm32 = Bits32 (opcode, 11, 0);
6815
6816                // index = TRUE; add = TRUE; wback = FALSE;
6817                index = true;
6818                add = true;
6819                wback = false;
6820
6821                // if t == 13 then UNPREDICTABLE;
6822                if (t == 13)
6823                    return false;
6824
6825                break;
6826
6827            case eEncodingT2:
6828                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6829                // if Rn == '1111' then SEE LDRSB (literal);
6830                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6831                // if P == '0' && W == '0' then UNDEFINED;
6832                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6833                    return false;
6834
6835                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6836                t = Bits32 (opcode, 15, 12);
6837                n = Bits32 (opcode, 19, 16);
6838                imm32 = Bits32 (opcode, 7, 0);
6839
6840                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6841                index = BitIsSet (opcode, 10);
6842                add = BitIsSet (opcode, 9);
6843                wback = BitIsSet (opcode, 8);
6844
6845                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6846                  if (((t == 13) || ((t == 15)
6847                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6848                      || (wback && (n == t)))
6849                    return false;
6850
6851                break;
6852
6853            case eEncodingA1:
6854            {
6855                // if Rn == '1111' then SEE LDRSB (literal);
6856                // if P == '0' && W == '1' then SEE LDRSBT;
6857                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6858                t = Bits32 (opcode, 15, 12);
6859                n = Bits32 (opcode, 19, 16);
6860
6861                uint32_t imm4H = Bits32 (opcode, 11, 8);
6862                uint32_t imm4L = Bits32 (opcode, 3, 0);
6863                imm32 = (imm4H << 4) | imm4L;
6864
6865                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6866                index = BitIsSet (opcode, 24);
6867                add = BitIsSet (opcode, 23);
6868                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6869
6870                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
6871                if ((t == 15) || (wback && (n == t)))
6872                    return false;
6873
6874                break;
6875            }
6876
6877            default:
6878                return false;
6879        }
6880
6881        uint64_t Rn = ReadCoreReg (n, &success);
6882        if (!success)
6883            return false;
6884
6885        addr_t offset_addr;
6886        addr_t address;
6887
6888        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6889        if (add)
6890            offset_addr = Rn + imm32;
6891        else
6892            offset_addr = Rn - imm32;
6893
6894        // address = if index then offset_addr else R[n];
6895        if (index)
6896            address = offset_addr;
6897        else
6898            address = Rn;
6899
6900        // R[t] = SignExtend(MemU[address,1], 32);
6901        Register base_reg;
6902        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6903
6904        EmulateInstruction::Context context;
6905        context.type = eContextRegisterLoad;
6906        context.SetRegisterPlusOffset (base_reg, address - Rn);
6907
6908        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
6909        if (!success)
6910            return false;
6911
6912        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
6913        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
6914            return false;
6915
6916        // if wback then R[n] = offset_addr;
6917        if (wback)
6918        {
6919            context.type = eContextAdjustBaseRegister;
6920            context.SetAddress (offset_addr);
6921            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6922                return false;
6923        }
6924    }
6925
6926    return true;
6927}
6928
6929// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6930// sign-extends it to form a 32-bit word, and writes tit to a register.
6931bool
6932EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6933{
6934#if 0
6935    if ConditionPassed() then
6936        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6937        base = Align(PC,4);
6938        address = if add then (base + imm32) else (base - imm32);
6939        R[t] = SignExtend(MemU[address,1], 32);
6940#endif
6941
6942    bool success = false;
6943
6944    if (ConditionPassed(opcode))
6945    {
6946        uint32_t t;
6947        uint32_t imm32;
6948        bool add;
6949
6950        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6951        switch (encoding)
6952        {
6953            case eEncodingT1:
6954                // if Rt == '1111' then SEE PLI;
6955                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6956                t = Bits32 (opcode, 15, 12);
6957                imm32 = Bits32 (opcode, 11, 0);
6958                add = BitIsSet (opcode, 23);
6959
6960                // if t == 13 then UNPREDICTABLE;
6961                if (t == 13)
6962                    return false;
6963
6964                break;
6965
6966            case eEncodingA1:
6967            {
6968                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6969                t = Bits32 (opcode, 15, 12);
6970                uint32_t imm4H = Bits32 (opcode, 11, 8);
6971                uint32_t imm4L = Bits32 (opcode, 3, 0);
6972                imm32 = (imm4H << 4) | imm4L;
6973                add = BitIsSet (opcode, 23);
6974
6975                // if t == 15 then UNPREDICTABLE;
6976                if (t == 15)
6977                    return false;
6978
6979                break;
6980            }
6981
6982            default:
6983                return false;
6984        }
6985
6986        // base = Align(PC,4);
6987        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6988        if (!success)
6989            return false;
6990        uint64_t base = AlignPC (pc_value);
6991
6992        // address = if add then (base + imm32) else (base - imm32);
6993        addr_t address;
6994        if (add)
6995            address = base + imm32;
6996        else
6997            address = base - imm32;
6998
6999        // R[t] = SignExtend(MemU[address,1], 32);
7000        Register base_reg;
7001        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7002
7003        EmulateInstruction::Context context;
7004        context.type = eContextRegisterLoad;
7005        context.SetRegisterPlusOffset (base_reg, address - base);
7006
7007        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7008        if (!success)
7009            return false;
7010
7011        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7012        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7013            return false;
7014    }
7015    return true;
7016}
7017
7018// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7019// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7020// shifted left by 0, 1, 2, or 3 bits.
7021bool
7022EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7023{
7024#if 0
7025    if ConditionPassed() then
7026        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7027        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7028        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7029        address = if index then offset_addr else R[n];
7030        R[t] = SignExtend(MemU[address,1], 32);
7031        if wback then R[n] = offset_addr;
7032#endif
7033
7034    bool success = false;
7035
7036    if (ConditionPassed(opcode))
7037    {
7038        uint32_t t;
7039        uint32_t n;
7040        uint32_t m;
7041        bool index;
7042        bool add;
7043        bool wback;
7044        ARM_ShifterType shift_t;
7045        uint32_t shift_n;
7046
7047        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7048        switch (encoding)
7049        {
7050            case eEncodingT1:
7051                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7052                t = Bits32 (opcode, 2, 0);
7053                n = Bits32 (opcode, 5, 3);
7054                m = Bits32 (opcode, 8, 6);
7055
7056                // index = TRUE; add = TRUE; wback = FALSE;
7057                index = true;
7058                add = true;
7059                wback = false;
7060
7061                // (shift_t, shift_n) = (SRType_LSL, 0);
7062                shift_t = SRType_LSL;
7063                shift_n = 0;
7064
7065                break;
7066
7067            case eEncodingT2:
7068                // if Rt == '1111' then SEE PLI;
7069                // if Rn == '1111' then SEE LDRSB (literal);
7070                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7071                t = Bits32 (opcode, 15, 12);
7072                n = Bits32 (opcode, 19, 16);
7073                m = Bits32 (opcode, 3, 0);
7074
7075                // index = TRUE; add = TRUE; wback = FALSE;
7076                index = true;
7077                add = true;
7078                wback = false;
7079
7080                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7081                shift_t = SRType_LSL;
7082                shift_n = Bits32 (opcode, 5, 4);
7083
7084                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7085                if ((t == 13) || BadReg (m))
7086                    return false;
7087                break;
7088
7089            case eEncodingA1:
7090                // if P == '0' && W == '1' then SEE LDRSBT;
7091                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7092                t = Bits32 (opcode, 15, 12);
7093                n = Bits32 (opcode, 19, 16);
7094                m = Bits32 (opcode, 3, 0);
7095
7096                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7097                index = BitIsSet (opcode, 24);
7098                add = BitIsSet (opcode, 23);
7099                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7100
7101                // (shift_t, shift_n) = (SRType_LSL, 0);
7102                shift_t = SRType_LSL;
7103                shift_n = 0;
7104
7105                // if t == 15 || m == 15 then UNPREDICTABLE;
7106                if ((t == 15) || (m == 15))
7107                    return false;
7108
7109                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7110                if (wback && ((n == 15) || (n == t)))
7111                    return false;
7112                break;
7113
7114            default:
7115                return false;
7116        }
7117
7118        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7119        if (!success)
7120            return false;
7121
7122        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7123        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7124
7125        addr_t offset_addr;
7126        addr_t address;
7127
7128        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7129        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7130        if (!success)
7131            return false;
7132
7133        if (add)
7134            offset_addr = Rn + offset;
7135        else
7136            offset_addr = Rn - offset;
7137
7138        // address = if index then offset_addr else R[n];
7139        if (index)
7140            address = offset_addr;
7141        else
7142            address = Rn;
7143
7144        // R[t] = SignExtend(MemU[address,1], 32);
7145        Register base_reg;
7146        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7147        Register offset_reg;
7148        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7149
7150        EmulateInstruction::Context context;
7151        context.type = eContextRegisterLoad;
7152        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7153
7154        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7155        if (!success)
7156            return false;
7157
7158        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7159        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7160            return false;
7161
7162        // if wback then R[n] = offset_addr;
7163        if (wback)
7164        {
7165            context.type = eContextAdjustBaseRegister;
7166            context.SetAddress (offset_addr);
7167            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7168                return false;
7169        }
7170    }
7171    return true;
7172}
7173
7174// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7175// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7176// pre-indexed addressing.
7177bool
7178EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7179{
7180#if 0
7181    if ConditionPassed() then
7182        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7183        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7184        address = if index then offset_addr else R[n];
7185        data = MemU[address,2];
7186        if wback then R[n] = offset_addr;
7187        if UnalignedSupport() || address<0> = '0' then
7188            R[t] = SignExtend(data, 32);
7189        else // Can only apply before ARMv7
7190            R[t] = bits(32) UNKNOWN;
7191#endif
7192
7193    bool success = false;
7194
7195    if (ConditionPassed(opcode))
7196    {
7197        uint32_t t;
7198        uint32_t n;
7199        uint32_t imm32;
7200        bool index;
7201        bool add;
7202        bool wback;
7203
7204        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7205        switch (encoding)
7206        {
7207            case eEncodingT1:
7208                // if Rn == '1111' then SEE LDRSH (literal);
7209                // if Rt == '1111' then SEE "Unallocated memory hints";
7210                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7211                t = Bits32 (opcode, 15, 12);
7212                n = Bits32 (opcode, 19, 16);
7213                imm32 = Bits32 (opcode, 11, 0);
7214
7215                // index = TRUE; add = TRUE; wback = FALSE;
7216                index = true;
7217                add = true;
7218                wback = false;
7219
7220                // if t == 13 then UNPREDICTABLE;
7221                if (t == 13)
7222                    return false;
7223
7224                break;
7225
7226            case eEncodingT2:
7227                // if Rn == '1111' then SEE LDRSH (literal);
7228                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7229                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7230                // if P == '0' && W == '0' then UNDEFINED;
7231                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7232                  return false;
7233
7234                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7235                t = Bits32 (opcode, 15, 12);
7236                n = Bits32 (opcode, 19, 16);
7237                imm32 = Bits32 (opcode, 7, 0);
7238
7239                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7240                index = BitIsSet (opcode, 10);
7241                add = BitIsSet (opcode, 9);
7242                wback = BitIsSet (opcode, 8);
7243
7244                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7245                if (BadReg (t) || (wback && (n == t)))
7246                    return false;
7247
7248                break;
7249
7250            case eEncodingA1:
7251            {
7252                // if Rn == '1111' then SEE LDRSH (literal);
7253                // if P == '0' && W == '1' then SEE LDRSHT;
7254                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7255                t = Bits32 (opcode, 15, 12);
7256                n = Bits32 (opcode, 19, 16);
7257                uint32_t imm4H = Bits32 (opcode, 11,8);
7258                uint32_t imm4L = Bits32 (opcode, 3, 0);
7259                imm32 = (imm4H << 4) | imm4L;
7260
7261                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7262                index = BitIsSet (opcode, 24);
7263                add = BitIsSet (opcode, 23);
7264                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7265
7266                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7267                if ((t == 15) || (wback && (n == t)))
7268                    return false;
7269
7270                break;
7271            }
7272
7273            default:
7274                return false;
7275        }
7276
7277        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7278        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7279        if (!success)
7280            return false;
7281
7282        addr_t offset_addr;
7283        if (add)
7284            offset_addr = Rn + imm32;
7285        else
7286            offset_addr = Rn - imm32;
7287
7288        // address = if index then offset_addr else R[n];
7289        addr_t address;
7290        if (index)
7291            address = offset_addr;
7292        else
7293            address = Rn;
7294
7295        // data = MemU[address,2];
7296        Register base_reg;
7297        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7298
7299        EmulateInstruction::Context context;
7300        context.type = eContextRegisterLoad;
7301        context.SetRegisterPlusOffset (base_reg, address - Rn);
7302
7303        uint64_t data = MemURead (context, address, 2, 0, &success);
7304        if (!success)
7305            return false;
7306
7307        // if wback then R[n] = offset_addr;
7308        if (wback)
7309        {
7310            context.type = eContextAdjustBaseRegister;
7311            context.SetAddress (offset_addr);
7312            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7313                return false;
7314        }
7315
7316        // if UnalignedSupport() || address<0> = '0' then
7317        if (UnalignedSupport() || BitIsClear (address, 0))
7318        {
7319            // R[t] = SignExtend(data, 32);
7320            int64_t signed_data = llvm::SignExtend64<16>(data);
7321            context.type = eContextRegisterLoad;
7322            context.SetRegisterPlusOffset (base_reg, address - Rn);
7323            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7324                return false;
7325        }
7326        else // Can only apply before ARMv7
7327        {
7328            // R[t] = bits(32) UNKNOWN;
7329            WriteBits32Unknown (t);
7330        }
7331    }
7332    return true;
7333}
7334
7335// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7336// sign-extends it to from a 32-bit word, and writes it to a register.
7337bool
7338EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7339{
7340#if 0
7341    if ConditionPassed() then
7342        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7343        base = Align(PC,4);
7344        address = if add then (base + imm32) else (base - imm32);
7345        data = MemU[address,2];
7346        if UnalignedSupport() || address<0> = '0' then
7347            R[t] = SignExtend(data, 32);
7348        else // Can only apply before ARMv7
7349            R[t] = bits(32) UNKNOWN;
7350#endif
7351
7352    bool success = false;
7353
7354    if (ConditionPassed(opcode))
7355    {
7356        uint32_t t;
7357        uint32_t imm32;
7358        bool add;
7359
7360        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7361        switch (encoding)
7362        {
7363            case eEncodingT1:
7364                // if Rt == '1111' then SEE "Unallocated memory hints";
7365                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7366                t = Bits32  (opcode, 15, 12);
7367                imm32 = Bits32 (opcode, 11, 0);
7368                add = BitIsSet (opcode, 23);
7369
7370                // if t == 13 then UNPREDICTABLE;
7371                if (t == 13)
7372                    return false;
7373
7374                break;
7375
7376            case eEncodingA1:
7377            {
7378                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7379                t = Bits32 (opcode, 15, 12);
7380                uint32_t imm4H = Bits32 (opcode, 11, 8);
7381                uint32_t imm4L = Bits32 (opcode, 3, 0);
7382                imm32 = (imm4H << 4) | imm4L;
7383                add = BitIsSet (opcode, 23);
7384
7385                // if t == 15 then UNPREDICTABLE;
7386                if (t == 15)
7387                    return false;
7388
7389                break;
7390            }
7391            default:
7392                return false;
7393        }
7394
7395        // base = Align(PC,4);
7396        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7397        if (!success)
7398            return false;
7399
7400        uint64_t base = AlignPC (pc_value);
7401
7402        addr_t address;
7403        // address = if add then (base + imm32) else (base - imm32);
7404        if (add)
7405            address = base + imm32;
7406        else
7407            address = base - imm32;
7408
7409        // data = MemU[address,2];
7410        Register base_reg;
7411        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7412
7413        EmulateInstruction::Context context;
7414        context.type = eContextRegisterLoad;
7415        context.SetRegisterPlusOffset (base_reg, imm32);
7416
7417        uint64_t data = MemURead (context, address, 2, 0, &success);
7418        if (!success)
7419            return false;
7420
7421        // if UnalignedSupport() || address<0> = '0' then
7422        if (UnalignedSupport() || BitIsClear (address, 0))
7423        {
7424            // R[t] = SignExtend(data, 32);
7425            int64_t signed_data = llvm::SignExtend64<16>(data);
7426            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7427                return false;
7428        }
7429        else // Can only apply before ARMv7
7430        {
7431            // R[t] = bits(32) UNKNOWN;
7432            WriteBits32Unknown (t);
7433        }
7434    }
7435    return true;
7436}
7437
7438// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7439// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7440// shifted left by 0, 1, 2, or 3 bits.
7441bool
7442EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7443{
7444#if 0
7445    if ConditionPassed() then
7446        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7447        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7448        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7449        address = if index then offset_addr else R[n];
7450        data = MemU[address,2];
7451        if wback then R[n] = offset_addr;
7452        if UnalignedSupport() || address<0> = '0' then
7453            R[t] = SignExtend(data, 32);
7454        else // Can only apply before ARMv7
7455            R[t] = bits(32) UNKNOWN;
7456#endif
7457
7458    bool success = false;
7459
7460    if (ConditionPassed(opcode))
7461    {
7462        uint32_t t;
7463        uint32_t n;
7464        uint32_t m;
7465        bool index;
7466        bool add;
7467        bool wback;
7468        ARM_ShifterType shift_t;
7469        uint32_t shift_n;
7470
7471        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7472        switch (encoding)
7473        {
7474            case eEncodingT1:
7475                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7476                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7477                t = Bits32 (opcode, 2, 0);
7478                n = Bits32 (opcode, 5, 3);
7479                m = Bits32 (opcode, 8, 6);
7480
7481                // index = TRUE; add = TRUE; wback = FALSE;
7482                index = true;
7483                add = true;
7484                wback = false;
7485
7486                // (shift_t, shift_n) = (SRType_LSL, 0);
7487                shift_t = SRType_LSL;
7488                shift_n = 0;
7489
7490                break;
7491
7492            case eEncodingT2:
7493                // if Rn == '1111' then SEE LDRSH (literal);
7494                // if Rt == '1111' then SEE "Unallocated memory hints";
7495                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7496                t = Bits32 (opcode, 15, 12);
7497                n = Bits32 (opcode, 19, 16);
7498                m = Bits32 (opcode, 3, 0);
7499
7500                // index = TRUE; add = TRUE; wback = FALSE;
7501                index = true;
7502                add = true;
7503                wback = false;
7504
7505                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7506                shift_t = SRType_LSL;
7507                shift_n = Bits32 (opcode, 5, 4);
7508
7509                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7510                if ((t == 13) || BadReg (m))
7511                    return false;
7512
7513                break;
7514
7515            case eEncodingA1:
7516                // if P == '0' && W == '1' then SEE LDRSHT;
7517                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7518                t = Bits32 (opcode, 15, 12);
7519                n = Bits32 (opcode, 19, 16);
7520                m = Bits32 (opcode, 3, 0);
7521
7522                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7523                index = BitIsSet (opcode, 24);
7524                add = BitIsSet (opcode, 23);
7525                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7526
7527                // (shift_t, shift_n) = (SRType_LSL, 0);
7528                shift_t = SRType_LSL;
7529                shift_n = 0;
7530
7531                // if t == 15 || m == 15 then UNPREDICTABLE;
7532                if ((t == 15) || (m == 15))
7533                    return false;
7534
7535                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7536                if (wback && ((n == 15) || (n == t)))
7537                    return false;
7538
7539                break;
7540
7541            default:
7542                break;
7543        }
7544
7545        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7546        if (!success)
7547            return false;
7548
7549        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7550        if (!success)
7551            return false;
7552
7553        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7554        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7555
7556        addr_t offset_addr;
7557        addr_t address;
7558
7559        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7560        if (add)
7561            offset_addr = Rn + offset;
7562        else
7563            offset_addr = Rn - offset;
7564
7565        // address = if index then offset_addr else R[n];
7566        if (index)
7567            address = offset_addr;
7568        else
7569            address = Rn;
7570
7571        // data = MemU[address,2];
7572        Register base_reg;
7573        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7574
7575        Register offset_reg;
7576        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7577
7578        EmulateInstruction::Context context;
7579        context.type = eContextRegisterLoad;
7580        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7581
7582        uint64_t data = MemURead (context, address, 2, 0, &success);
7583        if (!success)
7584            return false;
7585
7586        // if wback then R[n] = offset_addr;
7587        if (wback)
7588        {
7589            context.type = eContextAdjustBaseRegister;
7590            context.SetAddress (offset_addr);
7591            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7592                return false;
7593        }
7594
7595        // if UnalignedSupport() || address<0> = '0' then
7596        if (UnalignedSupport() || BitIsClear (address, 0))
7597        {
7598            // R[t] = SignExtend(data, 32);
7599            context.type = eContextRegisterLoad;
7600            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7601
7602            int64_t signed_data = llvm::SignExtend64<16>(data);
7603            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7604                return false;
7605        }
7606        else // Can only apply before ARMv7
7607        {
7608            // R[t] = bits(32) UNKNOWN;
7609            WriteBits32Unknown (t);
7610        }
7611    }
7612    return true;
7613}
7614
7615// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7616// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7617bool
7618EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7619{
7620#if 0
7621    if ConditionPassed() then
7622        EncodingSpecificOperations();
7623        rotated = ROR(R[m], rotation);
7624        R[d] = SignExtend(rotated<7:0>, 32);
7625#endif
7626
7627    bool success = false;
7628
7629    if (ConditionPassed(opcode))
7630    {
7631        uint32_t d;
7632        uint32_t m;
7633        uint32_t rotation;
7634
7635        // EncodingSpecificOperations();
7636        switch (encoding)
7637        {
7638            case eEncodingT1:
7639                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7640                d = Bits32 (opcode, 2, 0);
7641                m = Bits32 (opcode, 5, 3);
7642                rotation = 0;
7643
7644                break;
7645
7646            case eEncodingT2:
7647                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7648                d = Bits32 (opcode, 11, 8);
7649                m = Bits32 (opcode, 3, 0);
7650                rotation = Bits32 (opcode, 5, 4) << 3;
7651
7652                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7653                if (BadReg (d) || BadReg (m))
7654                    return false;
7655
7656                break;
7657
7658            case eEncodingA1:
7659                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7660                d = Bits32 (opcode, 15, 12);
7661                m = Bits32 (opcode, 3, 0);
7662                rotation = Bits32 (opcode, 11, 10) << 3;
7663
7664                // if d == 15 || m == 15 then UNPREDICTABLE;
7665                if ((d == 15) || (m == 15))
7666                    return false;
7667
7668                break;
7669
7670            default:
7671                return false;
7672        }
7673
7674        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7675        if (!success)
7676            return false;
7677
7678        // rotated = ROR(R[m], rotation);
7679        uint64_t rotated = ROR (Rm, rotation);
7680
7681        // R[d] = SignExtend(rotated<7:0>, 32);
7682        int64_t data = llvm::SignExtend64<8>(rotated);
7683
7684        Register source_reg;
7685        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7686
7687        EmulateInstruction::Context context;
7688        context.type = eContextRegisterLoad;
7689        context.SetRegister (source_reg);
7690
7691        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7692            return false;
7693    }
7694    return true;
7695}
7696
7697// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7698// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7699bool
7700EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7701{
7702#if 0
7703    if ConditionPassed() then
7704        EncodingSpecificOperations();
7705        rotated = ROR(R[m], rotation);
7706        R[d] = SignExtend(rotated<15:0>, 32);
7707#endif
7708
7709    bool success = false;
7710
7711    if (ConditionPassed(opcode))
7712    {
7713        uint32_t d;
7714        uint32_t m;
7715        uint32_t rotation;
7716
7717        // EncodingSpecificOperations();
7718        switch (encoding)
7719        {
7720            case eEncodingT1:
7721                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7722                d = Bits32 (opcode, 2, 0);
7723                m = Bits32 (opcode, 5, 3);
7724                rotation = 0;
7725
7726                break;
7727
7728            case eEncodingT2:
7729                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7730                d = Bits32 (opcode, 11, 8);
7731                m = Bits32 (opcode, 3, 0);
7732                rotation = Bits32 (opcode, 5, 4) << 3;
7733
7734                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7735                if (BadReg (d) || BadReg (m))
7736                    return false;
7737
7738                break;
7739
7740            case eEncodingA1:
7741                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7742                d = Bits32 (opcode, 15, 12);
7743                m = Bits32 (opcode, 3, 0);
7744                rotation = Bits32 (opcode, 11, 10) << 3;
7745
7746                // if d == 15 || m == 15 then UNPREDICTABLE;
7747                if ((d == 15) || (m == 15))
7748                    return false;
7749
7750                break;
7751
7752            default:
7753                return false;
7754        }
7755
7756        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7757        if (!success)
7758            return false;
7759
7760        // rotated = ROR(R[m], rotation);
7761        uint64_t rotated = ROR (Rm, rotation);
7762
7763        // R[d] = SignExtend(rotated<15:0>, 32);
7764        Register source_reg;
7765        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7766
7767        EmulateInstruction::Context context;
7768        context.type = eContextRegisterLoad;
7769        context.SetRegister (source_reg);
7770
7771        int64_t data = llvm::SignExtend64<16> (rotated);
7772        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7773            return false;
7774    }
7775
7776    return true;
7777}
7778
7779// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7780// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7781bool
7782EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7783{
7784#if 0
7785    if ConditionPassed() then
7786        EncodingSpecificOperations();
7787        rotated = ROR(R[m], rotation);
7788        R[d] = ZeroExtend(rotated<7:0>, 32);
7789#endif
7790
7791    bool success = false;
7792
7793    if (ConditionPassed(opcode))
7794    {
7795        uint32_t d;
7796        uint32_t m;
7797        uint32_t rotation;
7798
7799        // EncodingSpecificOperations();
7800        switch (encoding)
7801        {
7802            case eEncodingT1:
7803                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7804                d = Bits32 (opcode, 2, 0);
7805                m = Bits32 (opcode, 5, 3);
7806                rotation = 0;
7807
7808                break;
7809
7810            case eEncodingT2:
7811                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7812                d = Bits32 (opcode, 11, 8);
7813                m = Bits32 (opcode, 3, 0);
7814                  rotation = Bits32 (opcode, 5, 4) << 3;
7815
7816                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7817                if (BadReg (d) || BadReg (m))
7818                  return false;
7819
7820                break;
7821
7822            case eEncodingA1:
7823                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7824                d = Bits32 (opcode, 15, 12);
7825                m = Bits32 (opcode, 3, 0);
7826                rotation = Bits32 (opcode, 11, 10) << 3;
7827
7828                // if d == 15 || m == 15 then UNPREDICTABLE;
7829                if ((d == 15) || (m == 15))
7830                    return false;
7831
7832                break;
7833
7834            default:
7835                return false;
7836        }
7837
7838        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7839        if (!success)
7840            return false;
7841
7842        // rotated = ROR(R[m], rotation);
7843        uint64_t rotated = ROR (Rm, rotation);
7844
7845        // R[d] = ZeroExtend(rotated<7:0>, 32);
7846        Register source_reg;
7847        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7848
7849        EmulateInstruction::Context context;
7850        context.type = eContextRegisterLoad;
7851        context.SetRegister (source_reg);
7852
7853        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7854            return false;
7855    }
7856    return true;
7857}
7858
7859// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
7860// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7861bool
7862EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
7863{
7864#if 0
7865    if ConditionPassed() then
7866        EncodingSpecificOperations();
7867        rotated = ROR(R[m], rotation);
7868        R[d] = ZeroExtend(rotated<15:0>, 32);
7869#endif
7870
7871    bool success = false;
7872
7873    if (ConditionPassed(opcode))
7874    {
7875        uint32_t d;
7876        uint32_t m;
7877        uint32_t rotation;
7878
7879        switch (encoding)
7880        {
7881            case eEncodingT1:
7882                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7883                d = Bits32 (opcode, 2, 0);
7884                m = Bits32 (opcode, 5, 3);
7885                rotation = 0;
7886
7887                break;
7888
7889            case eEncodingT2:
7890                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7891                d = Bits32 (opcode, 11, 8);
7892                m = Bits32 (opcode, 3, 0);
7893                rotation = Bits32 (opcode, 5, 4) << 3;
7894
7895                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7896                if (BadReg (d) || BadReg (m))
7897                  return false;
7898
7899                break;
7900
7901            case eEncodingA1:
7902                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7903                d = Bits32 (opcode, 15, 12);
7904                m = Bits32 (opcode, 3, 0);
7905                rotation = Bits32 (opcode, 11, 10) << 3;
7906
7907                // if d == 15 || m == 15 then UNPREDICTABLE;
7908                if ((d == 15) || (m == 15))
7909                    return false;
7910
7911                break;
7912
7913            default:
7914                return false;
7915        }
7916
7917        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7918        if (!success)
7919            return false;
7920
7921        // rotated = ROR(R[m], rotation);
7922        uint64_t rotated = ROR (Rm, rotation);
7923
7924        // R[d] = ZeroExtend(rotated<15:0>, 32);
7925        Register source_reg;
7926        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7927
7928        EmulateInstruction::Context context;
7929        context.type = eContextRegisterLoad;
7930        context.SetRegister (source_reg);
7931
7932        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
7933            return false;
7934    }
7935    return true;
7936}
7937
7938// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
7939// word respectively.
7940bool
7941EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
7942{
7943#if 0
7944    if ConditionPassed() then
7945        EncodingSpecificOperations();
7946        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
7947            UNPREDICTABLE;
7948        else
7949            address = if increment then R[n] else R[n]-8;
7950            if wordhigher then address = address+4;
7951            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
7952            BranchWritePC(MemA[address,4]);
7953            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
7954#endif
7955
7956    bool success = false;
7957
7958    if (ConditionPassed(opcode))
7959    {
7960        uint32_t n;
7961        bool wback;
7962        bool increment;
7963        bool wordhigher;
7964
7965        // EncodingSpecificOperations();
7966        switch (encoding)
7967        {
7968            case eEncodingT1:
7969                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
7970                n = Bits32 (opcode, 19, 16);
7971                wback = BitIsSet (opcode, 21);
7972                increment = false;
7973                wordhigher = false;
7974
7975                // if n == 15 then UNPREDICTABLE;
7976                if (n == 15)
7977                    return false;
7978
7979                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7980                if (InITBlock() && !LastInITBlock())
7981                    return false;
7982
7983                break;
7984
7985            case eEncodingT2:
7986                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
7987                n = Bits32 (opcode, 19, 16);
7988                wback = BitIsSet (opcode, 21);
7989                increment = true;
7990                wordhigher = false;
7991
7992                // if n == 15 then UNPREDICTABLE;
7993                if (n == 15)
7994                    return false;
7995
7996                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7997                if (InITBlock() && !LastInITBlock())
7998                    return false;
7999
8000                break;
8001
8002            case eEncodingA1:
8003                // n = UInt(Rn);
8004                n = Bits32 (opcode, 19, 16);
8005
8006                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8007                wback = BitIsSet (opcode, 21);
8008                increment = BitIsSet (opcode, 23);
8009                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8010
8011                // if n == 15 then UNPREDICTABLE;
8012                if (n == 15)
8013                    return false;
8014
8015                break;
8016
8017            default:
8018                return false;
8019        }
8020
8021        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8022        if (!CurrentModeIsPrivileged ())
8023            // UNPREDICTABLE;
8024            return false;
8025        else
8026        {
8027            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8028            if (!success)
8029                return false;
8030
8031            addr_t address;
8032            // address = if increment then R[n] else R[n]-8;
8033            if (increment)
8034                address = Rn;
8035            else
8036                address = Rn - 8;
8037
8038            // if wordhigher then address = address+4;
8039            if (wordhigher)
8040                address = address + 4;
8041
8042            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8043            Register base_reg;
8044            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
8045
8046            EmulateInstruction::Context context;
8047            context.type = eContextReturnFromException;
8048            context.SetRegisterPlusOffset (base_reg, address - Rn);
8049
8050            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8051            if (!success)
8052                return false;
8053
8054            CPSRWriteByInstr (data, 15, true);
8055
8056            // BranchWritePC(MemA[address,4]);
8057            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8058            if (!success)
8059                return false;
8060
8061            BranchWritePC (context, data2);
8062
8063            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8064            if (wback)
8065            {
8066                context.type = eContextAdjustBaseRegister;
8067                if (increment)
8068                {
8069                    context.SetOffset (8);
8070                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8071                        return false;
8072                }
8073                else
8074                {
8075                    context.SetOffset (-8);
8076                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8077                        return false;
8078                }
8079            } // if wback
8080        }
8081    } // if ConditionPassed()
8082    return true;
8083}
8084
8085// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8086// and writes the result to the destination register.  It can optionally update the condition flags based on
8087// the result.
8088bool
8089EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8090{
8091#if 0
8092    // ARM pseudo code...
8093    if ConditionPassed() then
8094        EncodingSpecificOperations();
8095        result = R[n] EOR imm32;
8096        if d == 15 then         // Can only occur for ARM encoding
8097            ALUWritePC(result); // setflags is always FALSE here
8098        else
8099            R[d] = result;
8100            if setflags then
8101                APSR.N = result<31>;
8102                APSR.Z = IsZeroBit(result);
8103                APSR.C = carry;
8104                // APSR.V unchanged
8105#endif
8106
8107    bool success = false;
8108
8109    if (ConditionPassed(opcode))
8110    {
8111        uint32_t Rd, Rn;
8112        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8113        bool setflags;
8114        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8115        switch (encoding)
8116        {
8117        case eEncodingT1:
8118            Rd = Bits32(opcode, 11, 8);
8119            Rn = Bits32(opcode, 19, 16);
8120            setflags = BitIsSet(opcode, 20);
8121            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8122            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8123            if (Rd == 15 && setflags)
8124                return EmulateTEQImm (opcode, eEncodingT1);
8125            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8126                return false;
8127            break;
8128        case eEncodingA1:
8129            Rd = Bits32(opcode, 15, 12);
8130            Rn = Bits32(opcode, 19, 16);
8131            setflags = BitIsSet(opcode, 20);
8132            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8133
8134            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8135            if (Rd == 15 && setflags)
8136                return EmulateSUBSPcLrEtc (opcode, encoding);
8137            break;
8138        default:
8139            return false;
8140        }
8141
8142        // Read the first operand.
8143        uint32_t val1 = ReadCoreReg(Rn, &success);
8144        if (!success)
8145            return false;
8146
8147        uint32_t result = val1 ^ imm32;
8148
8149        EmulateInstruction::Context context;
8150        context.type = EmulateInstruction::eContextImmediate;
8151        context.SetNoArgs ();
8152
8153        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8154            return false;
8155    }
8156    return true;
8157}
8158
8159// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8160// optionally-shifted register value, and writes the result to the destination register.
8161// It can optionally update the condition flags based on the result.
8162bool
8163EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8164{
8165#if 0
8166    // ARM pseudo code...
8167    if ConditionPassed() then
8168        EncodingSpecificOperations();
8169        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8170        result = R[n] EOR shifted;
8171        if d == 15 then         // Can only occur for ARM encoding
8172            ALUWritePC(result); // setflags is always FALSE here
8173        else
8174            R[d] = result;
8175            if setflags then
8176                APSR.N = result<31>;
8177                APSR.Z = IsZeroBit(result);
8178                APSR.C = carry;
8179                // APSR.V unchanged
8180#endif
8181
8182    bool success = false;
8183
8184    if (ConditionPassed(opcode))
8185    {
8186        uint32_t Rd, Rn, Rm;
8187        ARM_ShifterType shift_t;
8188        uint32_t shift_n; // the shift applied to the value read from Rm
8189        bool setflags;
8190        uint32_t carry;
8191        switch (encoding)
8192        {
8193        case eEncodingT1:
8194            Rd = Rn = Bits32(opcode, 2, 0);
8195            Rm = Bits32(opcode, 5, 3);
8196            setflags = !InITBlock();
8197            shift_t = SRType_LSL;
8198            shift_n = 0;
8199            break;
8200        case eEncodingT2:
8201            Rd = Bits32(opcode, 11, 8);
8202            Rn = Bits32(opcode, 19, 16);
8203            Rm = Bits32(opcode, 3, 0);
8204            setflags = BitIsSet(opcode, 20);
8205            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8206            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8207            if (Rd == 15 && setflags)
8208                return EmulateTEQReg (opcode, eEncodingT1);
8209            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8210                return false;
8211            break;
8212        case eEncodingA1:
8213            Rd = Bits32(opcode, 15, 12);
8214            Rn = Bits32(opcode, 19, 16);
8215            Rm = Bits32(opcode, 3, 0);
8216            setflags = BitIsSet(opcode, 20);
8217            shift_n = DecodeImmShiftARM(opcode, shift_t);
8218
8219            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8220            if (Rd == 15 && setflags)
8221                return EmulateSUBSPcLrEtc (opcode, encoding);
8222            break;
8223        default:
8224            return false;
8225        }
8226
8227        // Read the first operand.
8228        uint32_t val1 = ReadCoreReg(Rn, &success);
8229        if (!success)
8230            return false;
8231
8232        // Read the second operand.
8233        uint32_t val2 = ReadCoreReg(Rm, &success);
8234        if (!success)
8235            return false;
8236
8237        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8238        uint32_t result = val1 ^ shifted;
8239
8240        EmulateInstruction::Context context;
8241        context.type = EmulateInstruction::eContextImmediate;
8242        context.SetNoArgs ();
8243
8244        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8245            return false;
8246    }
8247    return true;
8248}
8249
8250// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8251// writes the result to the destination register.  It can optionally update the condition flags based
8252// on the result.
8253bool
8254EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8255{
8256#if 0
8257    // ARM pseudo code...
8258    if ConditionPassed() then
8259        EncodingSpecificOperations();
8260        result = R[n] OR imm32;
8261        if d == 15 then         // Can only occur for ARM encoding
8262            ALUWritePC(result); // setflags is always FALSE here
8263        else
8264            R[d] = result;
8265            if setflags then
8266                APSR.N = result<31>;
8267                APSR.Z = IsZeroBit(result);
8268                APSR.C = carry;
8269                // APSR.V unchanged
8270#endif
8271
8272    bool success = false;
8273
8274    if (ConditionPassed(opcode))
8275    {
8276        uint32_t Rd, Rn;
8277        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8278        bool setflags;
8279        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8280        switch (encoding)
8281        {
8282        case eEncodingT1:
8283            Rd = Bits32(opcode, 11, 8);
8284            Rn = Bits32(opcode, 19, 16);
8285            setflags = BitIsSet(opcode, 20);
8286            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8287            // if Rn == '1111' then SEE MOV (immediate);
8288            if (Rn == 15)
8289                return EmulateMOVRdImm (opcode, eEncodingT2);
8290            if (BadReg(Rd) || Rn == 13)
8291                return false;
8292            break;
8293        case eEncodingA1:
8294            Rd = Bits32(opcode, 15, 12);
8295            Rn = Bits32(opcode, 19, 16);
8296            setflags = BitIsSet(opcode, 20);
8297            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8298
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 OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8324// value, and writes the result to the destination register.  It can optionally update the condition flags based
8325// on the result.
8326bool
8327EmulateInstructionARM::EmulateORRReg (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] OR 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 Rn == '1111' then SEE MOV (register);
8371            if (Rn == 15)
8372                return EmulateMOVRdRm (opcode, eEncodingT3);
8373            if (BadReg(Rd) || Rn == 13 || 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 == 15 && setflags)
8384                return EmulateSUBSPcLrEtc (opcode, encoding);
8385            break;
8386        default:
8387            return false;
8388        }
8389
8390        // Read the first operand.
8391        uint32_t val1 = ReadCoreReg(Rn, &success);
8392        if (!success)
8393            return false;
8394
8395        // Read the second operand.
8396        uint32_t val2 = ReadCoreReg(Rm, &success);
8397        if (!success)
8398            return false;
8399
8400        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8401        uint32_t result = val1 | shifted;
8402
8403        EmulateInstruction::Context context;
8404        context.type = EmulateInstruction::eContextImmediate;
8405        context.SetNoArgs ();
8406
8407        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8408            return false;
8409    }
8410    return true;
8411}
8412
8413// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8414// the destination register. It can optionally update the condition flags based on the result.
8415bool
8416EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8417{
8418#if 0
8419    // ARM pseudo code...
8420    if ConditionPassed() then
8421        EncodingSpecificOperations();
8422        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8423        if d == 15 then         // Can only occur for ARM encoding
8424            ALUWritePC(result); // setflags is always FALSE here
8425        else
8426            R[d] = result;
8427            if setflags then
8428                APSR.N = result<31>;
8429                APSR.Z = IsZeroBit(result);
8430                APSR.C = carry;
8431                APSR.V = overflow;
8432#endif
8433
8434    bool success = false;
8435
8436    uint32_t Rd; // the destination register
8437    uint32_t Rn; // the first operand
8438    bool setflags;
8439    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8440    switch (encoding) {
8441    case eEncodingT1:
8442        Rd = Bits32(opcode, 2, 0);
8443        Rn = Bits32(opcode, 5, 3);
8444        setflags = !InITBlock();
8445        imm32 = 0;
8446        break;
8447    case eEncodingT2:
8448        Rd = Bits32(opcode, 11, 8);
8449        Rn = Bits32(opcode, 19, 16);
8450        setflags = BitIsSet(opcode, 20);
8451        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8452        if (BadReg(Rd) || BadReg(Rn))
8453            return false;
8454        break;
8455    case eEncodingA1:
8456        Rd = Bits32(opcode, 15, 12);
8457        Rn = Bits32(opcode, 19, 16);
8458        setflags = BitIsSet(opcode, 20);
8459        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8460
8461        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8462        if (Rd == 15 && setflags)
8463            return EmulateSUBSPcLrEtc (opcode, encoding);
8464        break;
8465    default:
8466        return false;
8467    }
8468    // Read the register value from the operand register Rn.
8469    uint32_t reg_val = ReadCoreReg(Rn, &success);
8470    if (!success)
8471        return false;
8472
8473    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8474
8475    EmulateInstruction::Context context;
8476    context.type = EmulateInstruction::eContextImmediate;
8477    context.SetNoArgs ();
8478
8479    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8480        return false;
8481
8482    return true;
8483}
8484
8485// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8486// result to the destination register. It can optionally update the condition flags based on the result.
8487bool
8488EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8489{
8490#if 0
8491    // ARM pseudo code...
8492    if ConditionPassed() then
8493        EncodingSpecificOperations();
8494        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8495        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8496        if d == 15 then         // Can only occur for ARM encoding
8497            ALUWritePC(result); // setflags is always FALSE here
8498        else
8499            R[d] = result;
8500            if setflags then
8501                APSR.N = result<31>;
8502                APSR.Z = IsZeroBit(result);
8503                APSR.C = carry;
8504                APSR.V = overflow;
8505#endif
8506
8507    bool success = false;
8508
8509    uint32_t Rd; // the destination register
8510    uint32_t Rn; // the first operand
8511    uint32_t Rm; // the second operand
8512    bool setflags;
8513    ARM_ShifterType shift_t;
8514    uint32_t shift_n; // the shift applied to the value read from Rm
8515    switch (encoding) {
8516    case eEncodingT1:
8517        Rd = Bits32(opcode, 11, 8);
8518        Rn = Bits32(opcode, 19, 16);
8519        Rm = Bits32(opcode, 3, 0);
8520        setflags = BitIsSet(opcode, 20);
8521        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8522        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8523        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8524            return false;
8525        break;
8526    case eEncodingA1:
8527        Rd = Bits32(opcode, 15, 12);
8528        Rn = Bits32(opcode, 19, 16);
8529        Rm = Bits32(opcode, 3, 0);
8530        setflags = BitIsSet(opcode, 20);
8531        shift_n = DecodeImmShiftARM(opcode, shift_t);
8532
8533        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8534        if (Rd == 15 && setflags)
8535            return EmulateSUBSPcLrEtc (opcode, encoding);
8536        break;
8537    default:
8538        return false;
8539    }
8540    // Read the register value from register Rn.
8541    uint32_t val1 = ReadCoreReg(Rn, &success);
8542    if (!success)
8543        return false;
8544
8545    // Read the register value from register Rm.
8546    uint32_t val2 = ReadCoreReg(Rm, &success);
8547    if (!success)
8548        return false;
8549
8550    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8551    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8552
8553    EmulateInstruction::Context context;
8554    context.type = EmulateInstruction::eContextImmediate;
8555    context.SetNoArgs();
8556    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8557        return false;
8558
8559    return true;
8560}
8561
8562// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8563// an immediate value, and writes the result to the destination register. It can optionally update the condition
8564// flags based on the result.
8565bool
8566EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8567{
8568#if 0
8569    // ARM pseudo code...
8570    if ConditionPassed() then
8571        EncodingSpecificOperations();
8572        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8573        if d == 15 then
8574            ALUWritePC(result); // setflags is always FALSE here
8575        else
8576            R[d] = result;
8577            if setflags then
8578                APSR.N = result<31>;
8579                APSR.Z = IsZeroBit(result);
8580                APSR.C = carry;
8581                APSR.V = overflow;
8582#endif
8583
8584    bool success = false;
8585
8586    uint32_t Rd; // the destination register
8587    uint32_t Rn; // the first operand
8588    bool setflags;
8589    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8590    switch (encoding) {
8591    case eEncodingA1:
8592        Rd = Bits32(opcode, 15, 12);
8593        Rn = Bits32(opcode, 19, 16);
8594        setflags = BitIsSet(opcode, 20);
8595        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8596
8597        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8598        if (Rd == 15 && setflags)
8599            return EmulateSUBSPcLrEtc  (opcode, encoding);
8600        break;
8601    default:
8602        return false;
8603    }
8604    // Read the register value from the operand register Rn.
8605    uint32_t reg_val = ReadCoreReg(Rn, &success);
8606    if (!success)
8607        return false;
8608
8609    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8610
8611    EmulateInstruction::Context context;
8612    context.type = EmulateInstruction::eContextImmediate;
8613    context.SetNoArgs ();
8614
8615    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8616        return false;
8617
8618    return true;
8619}
8620
8621// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8622// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8623// condition flags based on the result.
8624bool
8625EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8626{
8627#if 0
8628    // ARM pseudo code...
8629    if ConditionPassed() then
8630        EncodingSpecificOperations();
8631        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8632        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8633        if d == 15 then
8634            ALUWritePC(result); // setflags is always FALSE here
8635        else
8636            R[d] = result;
8637            if setflags then
8638                APSR.N = result<31>;
8639                APSR.Z = IsZeroBit(result);
8640                APSR.C = carry;
8641                APSR.V = overflow;
8642#endif
8643
8644    bool success = false;
8645
8646    uint32_t Rd; // the destination register
8647    uint32_t Rn; // the first operand
8648    uint32_t Rm; // the second operand
8649    bool setflags;
8650    ARM_ShifterType shift_t;
8651    uint32_t shift_n; // the shift applied to the value read from Rm
8652    switch (encoding) {
8653    case eEncodingA1:
8654        Rd = Bits32(opcode, 15, 12);
8655        Rn = Bits32(opcode, 19, 16);
8656        Rm = Bits32(opcode, 3, 0);
8657        setflags = BitIsSet(opcode, 20);
8658        shift_n = DecodeImmShiftARM(opcode, shift_t);
8659
8660        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8661        if (Rd == 15 && setflags)
8662            return EmulateSUBSPcLrEtc (opcode, encoding);
8663        break;
8664    default:
8665        return false;
8666    }
8667    // Read the register value from register Rn.
8668    uint32_t val1 = ReadCoreReg(Rn, &success);
8669    if (!success)
8670        return false;
8671
8672    // Read the register value from register Rm.
8673    uint32_t val2 = ReadCoreReg(Rm, &success);
8674    if (!success)
8675        return false;
8676
8677    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8678    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8679
8680    EmulateInstruction::Context context;
8681    context.type = EmulateInstruction::eContextImmediate;
8682    context.SetNoArgs();
8683    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8684        return false;
8685
8686    return true;
8687}
8688
8689// Subtract with Carry (immediate) subtracts an immediate value and the value of
8690// NOT (Carry flag) from a register value, and writes the result to the destination register.
8691// It can optionally update the condition flags based on the result.
8692bool
8693EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8694{
8695#if 0
8696    // ARM pseudo code...
8697    if ConditionPassed() then
8698        EncodingSpecificOperations();
8699        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8700        if d == 15 then         // Can only occur for ARM encoding
8701            ALUWritePC(result); // setflags is always FALSE here
8702        else
8703            R[d] = result;
8704            if setflags then
8705                APSR.N = result<31>;
8706                APSR.Z = IsZeroBit(result);
8707                APSR.C = carry;
8708                APSR.V = overflow;
8709#endif
8710
8711    bool success = false;
8712
8713    uint32_t Rd; // the destination register
8714    uint32_t Rn; // the first operand
8715    bool setflags;
8716    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8717    switch (encoding) {
8718    case eEncodingT1:
8719        Rd = Bits32(opcode, 11, 8);
8720        Rn = Bits32(opcode, 19, 16);
8721        setflags = BitIsSet(opcode, 20);
8722        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8723        if (BadReg(Rd) || BadReg(Rn))
8724            return false;
8725        break;
8726    case eEncodingA1:
8727        Rd = Bits32(opcode, 15, 12);
8728        Rn = Bits32(opcode, 19, 16);
8729        setflags = BitIsSet(opcode, 20);
8730        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8731
8732        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8733        if (Rd == 15 && setflags)
8734            return EmulateSUBSPcLrEtc (opcode, encoding);
8735        break;
8736    default:
8737        return false;
8738    }
8739    // Read the register value from the operand register Rn.
8740    uint32_t reg_val = ReadCoreReg(Rn, &success);
8741    if (!success)
8742        return false;
8743
8744    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8745
8746    EmulateInstruction::Context context;
8747    context.type = EmulateInstruction::eContextImmediate;
8748    context.SetNoArgs ();
8749
8750    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8751        return false;
8752
8753    return true;
8754}
8755
8756// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8757// NOT (Carry flag) from a register value, and writes the result to the destination register.
8758// It can optionally update the condition flags based on the result.
8759bool
8760EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8761{
8762#if 0
8763    // ARM pseudo code...
8764    if ConditionPassed() then
8765        EncodingSpecificOperations();
8766        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8767        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8768        if d == 15 then         // Can only occur for ARM encoding
8769            ALUWritePC(result); // setflags is always FALSE here
8770        else
8771            R[d] = result;
8772            if setflags then
8773                APSR.N = result<31>;
8774                APSR.Z = IsZeroBit(result);
8775                APSR.C = carry;
8776                APSR.V = overflow;
8777#endif
8778
8779    bool success = false;
8780
8781    uint32_t Rd; // the destination register
8782    uint32_t Rn; // the first operand
8783    uint32_t Rm; // the second operand
8784    bool setflags;
8785    ARM_ShifterType shift_t;
8786    uint32_t shift_n; // the shift applied to the value read from Rm
8787    switch (encoding) {
8788    case eEncodingT1:
8789        Rd = Rn = Bits32(opcode, 2, 0);
8790        Rm = Bits32(opcode, 5, 3);
8791        setflags = !InITBlock();
8792        shift_t = SRType_LSL;
8793        shift_n = 0;
8794        break;
8795    case eEncodingT2:
8796        Rd = Bits32(opcode, 11, 8);
8797        Rn = Bits32(opcode, 19, 16);
8798        Rm = Bits32(opcode, 3, 0);
8799        setflags = BitIsSet(opcode, 20);
8800        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8801        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8802            return false;
8803        break;
8804    case eEncodingA1:
8805        Rd = Bits32(opcode, 15, 12);
8806        Rn = Bits32(opcode, 19, 16);
8807        Rm = Bits32(opcode, 3, 0);
8808        setflags = BitIsSet(opcode, 20);
8809        shift_n = DecodeImmShiftARM(opcode, shift_t);
8810
8811        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8812        if (Rd == 15 && setflags)
8813            return EmulateSUBSPcLrEtc (opcode, encoding);
8814        break;
8815    default:
8816        return false;
8817    }
8818    // Read the register value from register Rn.
8819    uint32_t val1 = ReadCoreReg(Rn, &success);
8820    if (!success)
8821        return false;
8822
8823    // Read the register value from register Rm.
8824    uint32_t val2 = ReadCoreReg(Rm, &success);
8825    if (!success)
8826        return false;
8827
8828    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8829    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8830
8831    EmulateInstruction::Context context;
8832    context.type = EmulateInstruction::eContextImmediate;
8833    context.SetNoArgs();
8834    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8835        return false;
8836
8837    return true;
8838}
8839
8840// This instruction subtracts an immediate value from a register value, and writes the result
8841// to the destination register.  It can optionally update the condition flags based on the result.
8842bool
8843EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
8844{
8845#if 0
8846    // ARM pseudo code...
8847    if ConditionPassed() then
8848        EncodingSpecificOperations();
8849        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8850        R[d] = result;
8851        if setflags then
8852            APSR.N = result<31>;
8853            APSR.Z = IsZeroBit(result);
8854            APSR.C = carry;
8855            APSR.V = overflow;
8856#endif
8857
8858    bool success = false;
8859
8860    uint32_t Rd; // the destination register
8861    uint32_t Rn; // the first operand
8862    bool setflags;
8863    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8864    switch (encoding) {
8865    case eEncodingT1:
8866        Rd = Bits32(opcode, 2, 0);
8867        Rn = Bits32(opcode, 5, 3);
8868        setflags = !InITBlock();
8869        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
8870        break;
8871    case eEncodingT2:
8872        Rd = Rn = Bits32(opcode, 10, 8);
8873        setflags = !InITBlock();
8874        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
8875        break;
8876    case eEncodingT3:
8877        Rd = Bits32(opcode, 11, 8);
8878        Rn = Bits32(opcode, 19, 16);
8879        setflags = BitIsSet(opcode, 20);
8880        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8881
8882        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
8883        if (Rd == 15 && setflags)
8884            return EmulateCMPImm (opcode, eEncodingT2);
8885
8886        // if Rn == '1101' then SEE SUB (SP minus immediate);
8887        if (Rn == 13)
8888            return EmulateSUBSPImm (opcode, eEncodingT2);
8889
8890        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
8891        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
8892            return false;
8893        break;
8894    case eEncodingT4:
8895        Rd = Bits32(opcode, 11, 8);
8896        Rn = Bits32(opcode, 19, 16);
8897        setflags = BitIsSet(opcode, 20);
8898        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
8899
8900        // if Rn == '1111' then SEE ADR;
8901        if (Rn == 15)
8902            return EmulateADR (opcode, eEncodingT2);
8903
8904        // if Rn == '1101' then SEE SUB (SP minus immediate);
8905        if (Rn == 13)
8906            return EmulateSUBSPImm (opcode, eEncodingT3);
8907
8908        if (BadReg(Rd))
8909            return false;
8910        break;
8911    default:
8912        return false;
8913    }
8914    // Read the register value from the operand register Rn.
8915    uint32_t reg_val = ReadCoreReg(Rn, &success);
8916    if (!success)
8917        return false;
8918
8919    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8920
8921    EmulateInstruction::Context context;
8922    context.type = EmulateInstruction::eContextImmediate;
8923    context.SetNoArgs ();
8924
8925    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8926        return false;
8927
8928    return true;
8929}
8930
8931// This instruction subtracts an immediate value from a register value, and writes the result
8932// to the destination register.  It can optionally update the condition flags based on the result.
8933bool
8934EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
8935{
8936#if 0
8937    // ARM pseudo code...
8938    if ConditionPassed() then
8939        EncodingSpecificOperations();
8940        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8941        if d == 15 then
8942            ALUWritePC(result); // setflags is always FALSE here
8943        else
8944            R[d] = result;
8945            if setflags then
8946                APSR.N = result<31>;
8947                APSR.Z = IsZeroBit(result);
8948                APSR.C = carry;
8949                APSR.V = overflow;
8950#endif
8951
8952    bool success = false;
8953
8954    uint32_t Rd; // the destination register
8955    uint32_t Rn; // the first operand
8956    bool setflags;
8957    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8958    switch (encoding) {
8959    case eEncodingA1:
8960        Rd = Bits32(opcode, 15, 12);
8961        Rn = Bits32(opcode, 19, 16);
8962        setflags = BitIsSet(opcode, 20);
8963        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8964
8965        // if Rn == '1111' && S == '0' then SEE ADR;
8966        if (Rn == 15 && !setflags)
8967            return EmulateADR (opcode, eEncodingA2);
8968
8969        // if Rn == '1101' then SEE SUB (SP minus immediate);
8970        if (Rn == 13)
8971            return EmulateSUBSPImm (opcode, eEncodingA1);
8972
8973        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8974        if (Rd == 15 && setflags)
8975            return EmulateSUBSPcLrEtc (opcode, encoding);
8976        break;
8977    default:
8978        return false;
8979    }
8980    // Read the register value from the operand register Rn.
8981    uint32_t reg_val = ReadCoreReg(Rn, &success);
8982    if (!success)
8983        return false;
8984
8985    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8986
8987    EmulateInstruction::Context context;
8988    context.type = EmulateInstruction::eContextImmediate;
8989    context.SetNoArgs ();
8990
8991    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8992        return false;
8993
8994    return true;
8995}
8996
8997// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
8998// immediate value.  It updates the condition flags based on the result, and discards the result.
8999bool
9000EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9001{
9002#if 0
9003    // ARM pseudo code...
9004    if ConditionPassed() then
9005        EncodingSpecificOperations();
9006        result = R[n] EOR imm32;
9007        APSR.N = result<31>;
9008        APSR.Z = IsZeroBit(result);
9009        APSR.C = carry;
9010        // APSR.V unchanged
9011#endif
9012
9013    bool success = false;
9014
9015    if (ConditionPassed(opcode))
9016    {
9017        uint32_t Rn;
9018        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9019        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9020        switch (encoding)
9021        {
9022        case eEncodingT1:
9023            Rn = Bits32(opcode, 19, 16);
9024            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9025            if (BadReg(Rn))
9026                return false;
9027            break;
9028        case eEncodingA1:
9029            Rn = Bits32(opcode, 19, 16);
9030            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9031            break;
9032        default:
9033            return false;
9034        }
9035
9036        // Read the first operand.
9037        uint32_t val1 = ReadCoreReg(Rn, &success);
9038        if (!success)
9039            return false;
9040
9041        uint32_t result = val1 ^ imm32;
9042
9043        EmulateInstruction::Context context;
9044        context.type = EmulateInstruction::eContextImmediate;
9045        context.SetNoArgs ();
9046
9047        if (!WriteFlags(context, result, carry))
9048            return false;
9049    }
9050    return true;
9051}
9052
9053// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9054// optionally-shifted register value.  It updates the condition flags based on the result, and discards
9055// the result.
9056bool
9057EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9058{
9059#if 0
9060    // ARM pseudo code...
9061    if ConditionPassed() then
9062        EncodingSpecificOperations();
9063        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9064        result = R[n] EOR shifted;
9065        APSR.N = result<31>;
9066        APSR.Z = IsZeroBit(result);
9067        APSR.C = carry;
9068        // APSR.V unchanged
9069#endif
9070
9071    bool success = false;
9072
9073    if (ConditionPassed(opcode))
9074    {
9075        uint32_t Rn, Rm;
9076        ARM_ShifterType shift_t;
9077        uint32_t shift_n; // the shift applied to the value read from Rm
9078        uint32_t carry;
9079        switch (encoding)
9080        {
9081        case eEncodingT1:
9082            Rn = Bits32(opcode, 19, 16);
9083            Rm = Bits32(opcode, 3, 0);
9084            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9085            if (BadReg(Rn) || BadReg(Rm))
9086                return false;
9087            break;
9088        case eEncodingA1:
9089            Rn = Bits32(opcode, 19, 16);
9090            Rm = Bits32(opcode, 3, 0);
9091            shift_n = DecodeImmShiftARM(opcode, shift_t);
9092            break;
9093        default:
9094            return false;
9095        }
9096
9097        // Read the first operand.
9098        uint32_t val1 = ReadCoreReg(Rn, &success);
9099        if (!success)
9100            return false;
9101
9102        // Read the second operand.
9103        uint32_t val2 = ReadCoreReg(Rm, &success);
9104        if (!success)
9105            return false;
9106
9107        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9108        uint32_t result = val1 ^ shifted;
9109
9110        EmulateInstruction::Context context;
9111        context.type = EmulateInstruction::eContextImmediate;
9112        context.SetNoArgs ();
9113
9114        if (!WriteFlags(context, result, carry))
9115            return false;
9116    }
9117    return true;
9118}
9119
9120// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9121// It updates the condition flags based on the result, and discards the result.
9122bool
9123EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9124{
9125#if 0
9126    // ARM pseudo code...
9127    if ConditionPassed() then
9128        EncodingSpecificOperations();
9129        result = R[n] AND imm32;
9130        APSR.N = result<31>;
9131        APSR.Z = IsZeroBit(result);
9132        APSR.C = carry;
9133        // APSR.V unchanged
9134#endif
9135
9136    bool success = false;
9137
9138    if (ConditionPassed(opcode))
9139    {
9140        uint32_t Rn;
9141        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9142        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9143        switch (encoding)
9144        {
9145        case eEncodingT1:
9146            Rn = Bits32(opcode, 19, 16);
9147            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9148            if (BadReg(Rn))
9149                return false;
9150            break;
9151        case eEncodingA1:
9152            Rn = Bits32(opcode, 19, 16);
9153            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9154            break;
9155        default:
9156            return false;
9157        }
9158
9159        // Read the first operand.
9160        uint32_t val1 = ReadCoreReg(Rn, &success);
9161        if (!success)
9162            return false;
9163
9164        uint32_t result = val1 & imm32;
9165
9166        EmulateInstruction::Context context;
9167        context.type = EmulateInstruction::eContextImmediate;
9168        context.SetNoArgs ();
9169
9170        if (!WriteFlags(context, result, carry))
9171            return false;
9172    }
9173    return true;
9174}
9175
9176// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9177// It updates the condition flags based on the result, and discards the result.
9178bool
9179EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9180{
9181#if 0
9182    // ARM pseudo code...
9183    if ConditionPassed() then
9184        EncodingSpecificOperations();
9185        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9186        result = R[n] AND shifted;
9187        APSR.N = result<31>;
9188        APSR.Z = IsZeroBit(result);
9189        APSR.C = carry;
9190        // APSR.V unchanged
9191#endif
9192
9193    bool success = false;
9194
9195    if (ConditionPassed(opcode))
9196    {
9197        uint32_t Rn, Rm;
9198        ARM_ShifterType shift_t;
9199        uint32_t shift_n; // the shift applied to the value read from Rm
9200        uint32_t carry;
9201        switch (encoding)
9202        {
9203        case eEncodingT1:
9204            Rn = Bits32(opcode, 2, 0);
9205            Rm = Bits32(opcode, 5, 3);
9206            shift_t = SRType_LSL;
9207            shift_n = 0;
9208            break;
9209        case eEncodingT2:
9210            Rn = Bits32(opcode, 19, 16);
9211            Rm = Bits32(opcode, 3, 0);
9212            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9213            if (BadReg(Rn) || BadReg(Rm))
9214                return false;
9215            break;
9216        case eEncodingA1:
9217            Rn = Bits32(opcode, 19, 16);
9218            Rm = Bits32(opcode, 3, 0);
9219            shift_n = DecodeImmShiftARM(opcode, shift_t);
9220            break;
9221        default:
9222            return false;
9223        }
9224
9225        // Read the first operand.
9226        uint32_t val1 = ReadCoreReg(Rn, &success);
9227        if (!success)
9228            return false;
9229
9230        // Read the second operand.
9231        uint32_t val2 = ReadCoreReg(Rm, &success);
9232        if (!success)
9233            return false;
9234
9235        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9236        uint32_t result = val1 & shifted;
9237
9238        EmulateInstruction::Context context;
9239        context.type = EmulateInstruction::eContextImmediate;
9240        context.SetNoArgs ();
9241
9242        if (!WriteFlags(context, result, carry))
9243            return false;
9244    }
9245    return true;
9246}
9247
9248// A8.6.216 SUB (SP minus register)
9249bool
9250EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9251{
9252#if 0
9253    if ConditionPassed() then
9254        EncodingSpecificOperations();
9255        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9256        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9257        if d == 15 then // Can only occur for ARM encoding
9258            ALUWritePC(result); // setflags is always FALSE here
9259        else
9260            R[d] = result;
9261            if setflags then
9262                APSR.N = result<31>;
9263                APSR.Z = IsZeroBit(result);
9264                APSR.C = carry;
9265                APSR.V = overflow;
9266#endif
9267
9268    bool success = false;
9269
9270    if (ConditionPassed(opcode))
9271    {
9272        uint32_t d;
9273        uint32_t m;
9274        bool setflags;
9275        ARM_ShifterType shift_t;
9276        uint32_t shift_n;
9277
9278        switch (encoding)
9279        {
9280            case eEncodingT1:
9281                // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9282                d = Bits32 (opcode, 11, 8);
9283                m = Bits32 (opcode, 3, 0);
9284                setflags = BitIsSet (opcode, 20);
9285
9286                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9287                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9288
9289                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9290                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9291                    return false;
9292
9293                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9294                if ((d == 15) || BadReg (m))
9295                    return false;
9296                break;
9297
9298            case eEncodingA1:
9299                // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9300                d = Bits32 (opcode, 15, 12);
9301                m = Bits32 (opcode, 3, 0);
9302                setflags = BitIsSet (opcode, 20);
9303
9304                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9305                if (d == 15 && setflags)
9306                    EmulateSUBSPcLrEtc (opcode, encoding);
9307
9308                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9309                shift_n = DecodeImmShiftARM (opcode, shift_t);
9310                break;
9311
9312            default:
9313                return false;
9314        }
9315
9316        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9317        uint32_t Rm = ReadCoreReg (m, &success);
9318        if (!success)
9319            return false;
9320
9321        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9322
9323        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9324        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9325        if (!success)
9326            return false;
9327
9328        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9329
9330        EmulateInstruction::Context context;
9331        context.type = eContextSubtraction;
9332        Register sp_reg;
9333        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
9334        Register dwarf_reg;
9335        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9336        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9337
9338        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9339            return false;
9340    }
9341    return true;
9342}
9343
9344
9345// A8.6.7 ADD (register-shifted register)
9346bool
9347EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9348{
9349#if 0
9350    if ConditionPassed() then
9351        EncodingSpecificOperations();
9352        shift_n = UInt(R[s]<7:0>);
9353        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9354        (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9355        R[d] = result;
9356        if setflags then
9357            APSR.N = result<31>;
9358            APSR.Z = IsZeroBit(result);
9359            APSR.C = carry;
9360            APSR.V = overflow;
9361#endif
9362
9363    bool success = false;
9364
9365    if (ConditionPassed(opcode))
9366    {
9367        uint32_t d;
9368        uint32_t n;
9369        uint32_t m;
9370        uint32_t s;
9371        bool setflags;
9372        ARM_ShifterType shift_t;
9373
9374        switch (encoding)
9375        {
9376            case eEncodingA1:
9377                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9378                d = Bits32 (opcode, 15, 12);
9379                n = Bits32 (opcode, 19, 16);
9380                m = Bits32 (opcode, 3, 0);
9381                s = Bits32 (opcode, 11, 8);
9382
9383                // setflags = (S == ‘1’); shift_t = DecodeRegShift(type);
9384                setflags = BitIsSet (opcode, 20);
9385                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9386
9387                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9388                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9389                    return false;
9390                break;
9391
9392            default:
9393                return false;
9394        }
9395
9396        // shift_n = UInt(R[s]<7:0>);
9397        uint32_t Rs = ReadCoreReg (s, &success);
9398        if (!success)
9399            return false;
9400
9401        uint32_t shift_n = Bits32 (Rs, 7, 0);
9402
9403        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9404        uint32_t Rm = ReadCoreReg (m, &success);
9405        if (!success)
9406            return false;
9407
9408        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9409
9410        // (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9411        uint32_t Rn = ReadCoreReg (n, &success);
9412        if (!success)
9413            return false;
9414
9415        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9416
9417        // R[d] = result;
9418        EmulateInstruction::Context context;
9419        context.type = eContextAddition;
9420        Register reg_n;
9421        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
9422        Register reg_m;
9423        reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9424
9425        context.SetRegisterRegisterOperands (reg_n, reg_m);
9426
9427        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9428            return false;
9429
9430        // if setflags then
9431            // APSR.N = result<31>;
9432            // APSR.Z = IsZeroBit(result);
9433            // APSR.C = carry;
9434            // APSR.V = overflow;
9435        if (setflags)
9436            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9437    }
9438    return true;
9439}
9440
9441// A8.6.213 SUB (register)
9442bool
9443EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9444{
9445#if 0
9446    if ConditionPassed() then
9447        EncodingSpecificOperations();
9448        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9449        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9450        if d == 15 then // Can only occur for ARM encoding
9451            ALUWritePC(result); // setflags is always FALSE here
9452        else
9453            R[d] = result;
9454            if setflags then
9455                APSR.N = result<31>;
9456                APSR.Z = IsZeroBit(result);
9457                APSR.C = carry;
9458                APSR.V = overflow;
9459#endif
9460
9461    bool success = false;
9462
9463    if (ConditionPassed(opcode))
9464    {
9465        uint32_t d;
9466        uint32_t n;
9467        uint32_t m;
9468        bool setflags;
9469        ARM_ShifterType shift_t;
9470        uint32_t shift_n;
9471
9472        switch (encoding)
9473        {
9474            case eEncodingT1:
9475                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9476                d = Bits32 (opcode, 2, 0);
9477                n = Bits32 (opcode, 5, 3);
9478                m = Bits32 (opcode, 8, 6);
9479                setflags = !InITBlock();
9480
9481                // (shift_t, shift_n) = (SRType_LSL, 0);
9482                shift_t = SRType_LSL;
9483                shift_n = 0;
9484
9485                break;
9486
9487            case eEncodingT2:
9488                // if Rd == ‘1111’ && S == ‘1’ then SEE CMP (register);
9489                // if Rn == ‘1101’ then SEE SUB (SP minus register);
9490                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9491                d = Bits32 (opcode, 11, 8);
9492                n = Bits32 (opcode, 19, 16);
9493                m = Bits32 (opcode, 3, 0);
9494                setflags = BitIsSet (opcode, 20);
9495
9496                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9497                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9498
9499                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9500                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9501                    return false;
9502
9503                break;
9504
9505            case eEncodingA1:
9506                // if Rn == ‘1101’ then SEE SUB (SP minus register);
9507                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9508                d = Bits32 (opcode, 15, 12);
9509                n = Bits32 (opcode, 19, 16);
9510                m = Bits32 (opcode, 3, 0);
9511                setflags = BitIsSet (opcode, 20);
9512
9513                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9514                if ((d == 15) && setflags)
9515                    EmulateSUBSPcLrEtc (opcode, encoding);
9516
9517                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9518                shift_n = DecodeImmShiftARM (opcode, shift_t);
9519
9520                break;
9521
9522            default:
9523                return false;
9524        }
9525
9526        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9527        uint32_t Rm = ReadCoreReg (m, &success);
9528        if (!success)
9529            return false;
9530
9531        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9532
9533        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9534        uint32_t Rn = ReadCoreReg (n, &success);
9535        if (!success)
9536            return false;
9537
9538        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9539
9540        // if d == 15 then // Can only occur for ARM encoding
9541            // ALUWritePC(result); // setflags is always FALSE here
9542        // else
9543            // R[d] = result;
9544            // if setflags then
9545                // APSR.N = result<31>;
9546                // APSR.Z = IsZeroBit(result);
9547                // APSR.C = carry;
9548                // APSR.V = overflow;
9549
9550        EmulateInstruction::Context context;
9551        context.type = eContextSubtraction;
9552        Register reg_n;
9553        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9554        Register reg_m;
9555        reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9556        context.SetRegisterRegisterOperands (reg_n, reg_m);
9557
9558        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9559            return false;
9560    }
9561    return true;
9562}
9563
9564// A8.6.202 STREX
9565// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9566// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9567bool
9568EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9569{
9570#if 0
9571    if ConditionPassed() then
9572        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9573        address = R[n] + imm32;
9574        if ExclusiveMonitorsPass(address,4) then
9575            MemA[address,4] = R[t];
9576            R[d] = 0;
9577        else
9578            R[d] = 1;
9579#endif
9580
9581    bool success = false;
9582
9583    if (ConditionPassed(opcode))
9584    {
9585        uint32_t d;
9586        uint32_t t;
9587        uint32_t n;
9588        uint32_t imm32;
9589        const uint32_t addr_byte_size = GetAddressByteSize();
9590
9591        switch (encoding)
9592        {
9593            case eEncodingT1:
9594                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9595                d = Bits32 (opcode, 11, 8);
9596                t = Bits32 (opcode, 15, 12);
9597                n = Bits32 (opcode, 19, 16);
9598                imm32 = Bits32 (opcode, 7, 0) << 2;
9599
9600                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9601                if (BadReg (d) || BadReg (t) || (n == 15))
9602                  return false;
9603
9604                // if d == n || d == t then UNPREDICTABLE;
9605                if ((d == n) || (d == t))
9606                  return false;
9607
9608                break;
9609
9610            case eEncodingA1:
9611                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9612                d = Bits32 (opcode, 15, 12);
9613                t = Bits32 (opcode, 3, 0);
9614                n = Bits32 (opcode, 19, 16);
9615                imm32 = 0;
9616
9617                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9618                if ((d == 15) || (t == 15) || (n == 15))
9619                    return false;
9620
9621                // if d == n || d == t then UNPREDICTABLE;
9622                if ((d == n) || (d == t))
9623                    return false;
9624
9625                break;
9626
9627            default:
9628                return false;
9629        }
9630
9631        // address = R[n] + imm32;
9632        uint32_t Rn = ReadCoreReg (n, &success);
9633        if (!success)
9634            return false;
9635
9636        addr_t address = Rn + imm32;
9637
9638        Register base_reg;
9639        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9640        Register data_reg;
9641        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9642        EmulateInstruction::Context context;
9643        context.type = eContextRegisterStore;
9644        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9645
9646        // if ExclusiveMonitorsPass(address,4) then
9647        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9648        //                                                         always return true.
9649        if (true)
9650        {
9651            // MemA[address,4] = R[t];
9652            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9653            if (!success)
9654                return false;
9655
9656            if (!MemAWrite (context, address, Rt, addr_byte_size))
9657                return false;
9658
9659            // R[d] = 0;
9660            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9661                return false;
9662        }
9663        else
9664        {
9665            // R[d] = 1;
9666            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9667                return false;
9668        }
9669    }
9670    return true;
9671}
9672
9673// A8.6.197 STRB (immediate, ARM)
9674bool
9675EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9676{
9677#if 0
9678    if ConditionPassed() then
9679        EncodingSpecificOperations();
9680        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9681        address = if index then offset_addr else R[n];
9682        MemU[address,1] = R[t]<7:0>;
9683        if wback then R[n] = offset_addr;
9684#endif
9685
9686    bool success = false;
9687
9688    if (ConditionPassed(opcode))
9689    {
9690        uint32_t t;
9691        uint32_t n;
9692        uint32_t imm32;
9693        bool index;
9694        bool add;
9695        bool wback;
9696
9697        switch (encoding)
9698        {
9699            case eEncodingA1:
9700                // if P == ‘0’ && W == ‘1’ then SEE STRBT;
9701                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9702                t = Bits32 (opcode, 15, 12);
9703                n = Bits32 (opcode, 19, 16);
9704                imm32 = Bits32 (opcode, 11, 0);
9705
9706                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9707                index = BitIsSet (opcode, 24);
9708                add = BitIsSet (opcode, 23);
9709                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9710
9711                // if t == 15 then UNPREDICTABLE;
9712                if (t == 15)
9713                    return false;
9714
9715                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9716                if (wback && ((n == 15) || (n == t)))
9717                    return false;
9718
9719                break;
9720
9721            default:
9722                return false;
9723        }
9724
9725        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9726        uint32_t Rn = ReadCoreReg (n, &success);
9727        if (!success)
9728            return false;
9729
9730        addr_t offset_addr;
9731        if (add)
9732            offset_addr = Rn + imm32;
9733        else
9734            offset_addr = Rn - imm32;
9735
9736        // address = if index then offset_addr else R[n];
9737        addr_t address;
9738        if (index)
9739            address = offset_addr;
9740        else
9741            address = Rn;
9742
9743        // MemU[address,1] = R[t]<7:0>;
9744        uint32_t Rt = ReadCoreReg (t, &success);
9745        if (!success)
9746            return false;
9747
9748        Register base_reg;
9749        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9750        Register data_reg;
9751        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9752        EmulateInstruction::Context context;
9753        context.type = eContextRegisterStore;
9754        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9755
9756        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9757            return false;
9758
9759        // if wback then R[n] = offset_addr;
9760        if (wback)
9761        {
9762            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9763                return false;
9764        }
9765    }
9766    return true;
9767}
9768
9769// A8.6.194 STR (immediate, ARM)
9770bool
9771EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9772{
9773#if 0
9774    if ConditionPassed() then
9775        EncodingSpecificOperations();
9776        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9777        address = if index then offset_addr else R[n];
9778        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9779        if wback then R[n] = offset_addr;
9780#endif
9781
9782    bool success = false;
9783
9784    if (ConditionPassed(opcode))
9785    {
9786        uint32_t t;
9787        uint32_t n;
9788        uint32_t imm32;
9789        bool index;
9790        bool add;
9791        bool wback;
9792
9793        const uint32_t addr_byte_size = GetAddressByteSize();
9794
9795        switch (encoding)
9796        {
9797            case eEncodingA1:
9798                // if P == ‘0’ && W == ‘1’ then SEE STRT;
9799                // if Rn == ‘1101’ && P == ‘1’ && U == ‘0’ && W == ‘1’ && imm12 == ‘000000000100’ then SEE PUSH;
9800                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9801                t = Bits32 (opcode, 15, 12);
9802                n = Bits32 (opcode, 19, 16);
9803                imm32 = Bits32 (opcode, 11, 0);
9804
9805                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9806                index = BitIsSet (opcode, 24);
9807                add = BitIsSet (opcode, 23);
9808                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9809
9810                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9811                if (wback && ((n == 15) || (n == t)))
9812                    return false;
9813
9814                break;
9815
9816            default:
9817                return false;
9818        }
9819
9820        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9821        uint32_t Rn = ReadCoreReg (n, &success);
9822        if (!success)
9823            return false;
9824
9825        addr_t offset_addr;
9826        if (add)
9827            offset_addr = Rn + imm32;
9828        else
9829            offset_addr = Rn - imm32;
9830
9831        // address = if index then offset_addr else R[n];
9832        addr_t address;
9833        if (index)
9834            address = offset_addr;
9835        else
9836            address = Rn;
9837
9838        Register base_reg;
9839        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9840        Register data_reg;
9841        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9842        EmulateInstruction::Context context;
9843        context.type = eContextRegisterStore;
9844        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9845
9846        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9847        uint32_t Rt = ReadCoreReg (t, &success);
9848        if (!success)
9849            return false;
9850
9851        if (t == 15)
9852        {
9853            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
9854            if (!success)
9855                return false;
9856
9857            if (!MemUWrite (context, address, pc_value, addr_byte_size))
9858                return false;
9859        }
9860        else
9861        {
9862            if (!MemUWrite (context, address, Rt, addr_byte_size))
9863                  return false;
9864        }
9865
9866        // if wback then R[n] = offset_addr;
9867        if (wback)
9868        {
9869            context.type = eContextAdjustBaseRegister;
9870            context.SetImmediate (offset_addr);
9871
9872            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9873                return false;
9874        }
9875    }
9876    return true;
9877}
9878
9879// A8.6.66 LDRD (immediate)
9880// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
9881// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
9882bool
9883EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
9884{
9885#if 0
9886    if ConditionPassed() then
9887        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9888        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9889        address = if index then offset_addr else R[n];
9890        R[t] = MemA[address,4];
9891        R[t2] = MemA[address+4,4];
9892        if wback then R[n] = offset_addr;
9893#endif
9894
9895    bool success = false;
9896
9897    if (ConditionPassed(opcode))
9898    {
9899        uint32_t t;
9900        uint32_t t2;
9901        uint32_t n;
9902        uint32_t imm32;
9903        bool index;
9904        bool add;
9905        bool wback;
9906
9907        switch (encoding)
9908        {
9909            case eEncodingT1:
9910                //if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
9911                //if Rn == ‘1111’ then SEE LDRD (literal);
9912                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9913                t = Bits32 (opcode, 15, 12);
9914                t2 = Bits32 (opcode, 11, 8);
9915                n = Bits32 (opcode, 19, 16);
9916                imm32 = Bits32 (opcode, 7, 0) << 2;
9917
9918                //index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
9919                index = BitIsSet (opcode, 24);
9920                add = BitIsSet (opcode, 23);
9921                wback = BitIsSet (opcode, 21);
9922
9923                //if wback && (n == t || n == t2) then UNPREDICTABLE;
9924                if (wback && ((n == t) || (n == t2)))
9925                    return false;
9926
9927                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
9928                if (BadReg (t) || BadReg (t2) || (t == t2))
9929                    return false;
9930
9931                break;
9932
9933            case eEncodingA1:
9934                //if Rn == ‘1111’ then SEE LDRD (literal);
9935                //if Rt<0> == ‘1’ then UNPREDICTABLE;
9936                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
9937                t = Bits32 (opcode, 15, 12);
9938                if (BitIsSet (t, 0))
9939                    return false;
9940                t2 = t + 1;
9941                n = Bits32 (opcode, 19, 16);
9942                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
9943
9944                //index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9945                index = BitIsSet (opcode, 24);
9946                add = BitIsSet (opcode, 23);
9947                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9948
9949                //if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
9950                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
9951                    return false;
9952
9953                //if wback && (n == t || n == t2) then UNPREDICTABLE;
9954                if (wback && ((n == t) || (n == t2)))
9955                    return false;
9956
9957                //if t2 == 15 then UNPREDICTABLE;
9958                if (t2 == 15)
9959                    return false;
9960
9961                break;
9962
9963            default:
9964                return false;
9965        }
9966
9967        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9968        uint32_t Rn = ReadCoreReg (n, &success);
9969        if (!success)
9970            return false;
9971
9972        addr_t offset_addr;
9973        if (add)
9974                  offset_addr = Rn + imm32;
9975        else
9976            offset_addr = Rn - imm32;
9977
9978        //address = if index then offset_addr else R[n];
9979        addr_t address;
9980        if (index)
9981            address = offset_addr;
9982        else
9983            address = Rn;
9984
9985        //R[t] = MemA[address,4];
9986        Register base_reg;
9987        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9988
9989        EmulateInstruction::Context context;
9990        context.type = eContextRegisterLoad;
9991        context.SetRegisterPlusOffset (base_reg, address - Rn);
9992
9993        const uint32_t addr_byte_size = GetAddressByteSize();
9994        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
9995        if (!success)
9996            return false;
9997
9998        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
9999            return false;
10000
10001        //R[t2] = MemA[address+4,4];
10002
10003        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10004        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10005        if (!success)
10006            return false;
10007
10008        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10009            return false;
10010
10011        //if wback then R[n] = offset_addr;
10012        if (wback)
10013        {
10014            context.type = eContextAdjustBaseRegister;
10015            context.SetAddress (offset_addr);
10016
10017            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10018                return false;
10019        }
10020    }
10021    return true;
10022}
10023
10024// A8.6.68 LDRD (register)
10025// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10026// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10027bool
10028EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10029{
10030#if 0
10031    if ConditionPassed() then
10032        EncodingSpecificOperations();
10033        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10034        address = if index then offset_addr else R[n];
10035        R[t] = MemA[address,4];
10036        R[t2] = MemA[address+4,4];
10037        if wback then R[n] = offset_addr;
10038#endif
10039
10040    bool success = false;
10041
10042    if (ConditionPassed(opcode))
10043    {
10044        uint32_t t;
10045        uint32_t t2;
10046        uint32_t n;
10047        uint32_t m;
10048        bool index;
10049        bool add;
10050        bool wback;
10051
10052        switch (encoding)
10053        {
10054            case eEncodingA1:
10055                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10056                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10057                t = Bits32 (opcode, 15, 12);
10058                if (BitIsSet (t, 0))
10059                    return false;
10060                t2 = t + 1;
10061                n = Bits32 (opcode, 19, 16);
10062                m = Bits32 (opcode, 3, 0);
10063
10064                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10065                index = BitIsSet (opcode, 24);
10066                add = BitIsSet (opcode, 23);
10067                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10068
10069                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10070                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10071                  return false;
10072
10073                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10074                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10075                  return false;
10076
10077                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10078                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10079                  return false;
10080
10081                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10082                if ((ArchVersion() < 6) && wback && (m == n))
10083                  return false;
10084                break;
10085
10086            default:
10087                return false;
10088        }
10089
10090        uint32_t Rn = ReadCoreReg (n, &success);
10091        if (!success)
10092            return false;
10093        Register base_reg;
10094        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10095
10096        uint32_t Rm = ReadCoreReg (m, &success);
10097        if (!success)
10098            return false;
10099        Register offset_reg;
10100        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10101
10102        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10103        addr_t offset_addr;
10104        if (add)
10105            offset_addr = Rn + Rm;
10106        else
10107            offset_addr = Rn - Rm;
10108
10109        // address = if index then offset_addr else R[n];
10110        addr_t address;
10111        if (index)
10112            address = offset_addr;
10113        else
10114            address = Rn;
10115
10116        EmulateInstruction::Context context;
10117        context.type = eContextRegisterLoad;
10118        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10119
10120        // R[t] = MemA[address,4];
10121        const uint32_t addr_byte_size = GetAddressByteSize();
10122        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10123        if (!success)
10124            return false;
10125
10126        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10127            return false;
10128
10129        // R[t2] = MemA[address+4,4];
10130
10131        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10132        if (!success)
10133            return false;
10134
10135        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10136            return false;
10137
10138        // if wback then R[n] = offset_addr;
10139        if (wback)
10140        {
10141            context.type = eContextAdjustBaseRegister;
10142            context.SetAddress (offset_addr);
10143
10144            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10145                return false;
10146        }
10147    }
10148    return true;
10149}
10150
10151// A8.6.200 STRD (immediate)
10152// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10153// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10154bool
10155EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10156{
10157#if 0
10158    if ConditionPassed() then
10159        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10160        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10161        address = if index then offset_addr else R[n];
10162        MemA[address,4] = R[t];
10163        MemA[address+4,4] = R[t2];
10164        if wback then R[n] = offset_addr;
10165#endif
10166
10167    bool success = false;
10168
10169    if (ConditionPassed(opcode))
10170    {
10171        uint32_t t;
10172        uint32_t t2;
10173        uint32_t n;
10174        uint32_t imm32;
10175        bool index;
10176        bool add;
10177        bool wback;
10178
10179        switch (encoding)
10180        {
10181            case eEncodingT1:
10182                // if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10183                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10184                t = Bits32 (opcode, 15, 12);
10185                t2 = Bits32 (opcode, 11, 8);
10186                n = Bits32 (opcode, 19, 16);
10187                imm32 = Bits32 (opcode, 7, 0) << 2;
10188
10189                // index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
10190                index = BitIsSet (opcode, 24);
10191                add = BitIsSet (opcode, 23);
10192                wback = BitIsSet (opcode, 21);
10193
10194                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10195                if (wback && ((n == t) || (n == t2)))
10196                    return false;
10197
10198                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10199                if ((n == 15) || BadReg (t) || BadReg (t2))
10200                    return false;
10201
10202                break;
10203
10204            case eEncodingA1:
10205                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10206                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10207                t = Bits32 (opcode, 15, 12);
10208                if (BitIsSet (t, 0))
10209                    return false;
10210
10211                t2 = t + 1;
10212                n = Bits32 (opcode, 19, 16);
10213                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10214
10215                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10216                index = BitIsSet (opcode, 24);
10217                add = BitIsSet (opcode, 23);
10218                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10219
10220                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10221                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10222                    return false;
10223
10224                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10225                if (wback && ((n == 15) || (n == t) || (n == t2)))
10226                    return false;
10227
10228                // if t2 == 15 then UNPREDICTABLE;
10229                if (t2 == 15)
10230                    return false;
10231
10232                break;
10233
10234            default:
10235                return false;
10236        }
10237
10238        Register base_reg;
10239        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10240
10241        uint32_t Rn = ReadCoreReg (n, &success);
10242        if (!success)
10243            return false;
10244
10245        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10246        addr_t offset_addr;
10247        if (add)
10248            offset_addr = Rn + imm32;
10249        else
10250            offset_addr = Rn - imm32;
10251
10252        //address = if index then offset_addr else R[n];
10253        addr_t address;
10254        if (index)
10255            address = offset_addr;
10256        else
10257            address = Rn;
10258
10259        //MemA[address,4] = R[t];
10260        Register data_reg;
10261        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10262
10263        uint32_t data = ReadCoreReg (t, &success);
10264        if (!success)
10265            return false;
10266
10267        EmulateInstruction::Context context;
10268        context.type = eContextRegisterStore;
10269        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10270
10271        const uint32_t addr_byte_size = GetAddressByteSize();
10272
10273        if (!MemAWrite (context, address, data, addr_byte_size))
10274            return false;
10275
10276        //MemA[address+4,4] = R[t2];
10277        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t2);
10278        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10279
10280        data = ReadCoreReg (t2, &success);
10281        if (!success)
10282            return false;
10283
10284        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10285            return false;
10286
10287        //if wback then R[n] = offset_addr;
10288        if (wback)
10289        {
10290            context.type = eContextAdjustBaseRegister;
10291            context.SetAddress (offset_addr);
10292
10293            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10294                return false;
10295        }
10296    }
10297    return true;
10298}
10299
10300
10301// A8.6.201 STRD (register)
10302bool
10303EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10304{
10305#if 0
10306    if ConditionPassed() then
10307        EncodingSpecificOperations();
10308        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10309        address = if index then offset_addr else R[n];
10310        MemA[address,4] = R[t];
10311        MemA[address+4,4] = R[t2];
10312        if wback then R[n] = offset_addr;
10313#endif
10314
10315    bool success = false;
10316
10317    if (ConditionPassed(opcode))
10318    {
10319        uint32_t t;
10320        uint32_t t2;
10321        uint32_t n;
10322        uint32_t m;
10323        bool index;
10324        bool add;
10325        bool wback;
10326
10327        switch (encoding)
10328        {
10329            case eEncodingA1:
10330                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10331                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10332                t = Bits32 (opcode, 15, 12);
10333                if (BitIsSet (t, 0))
10334                   return false;
10335
10336                t2 = t+1;
10337                n = Bits32 (opcode, 19, 16);
10338                m = Bits32 (opcode, 3, 0);
10339
10340                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10341                index = BitIsSet (opcode, 24);
10342                add = BitIsSet (opcode, 23);
10343                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10344
10345                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10346                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10347                   return false;
10348
10349                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10350                if ((t2 == 15) || (m == 15))
10351                   return false;
10352
10353                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10354                if (wback && ((n == 15) || (n == t) || (n == t2)))
10355                   return false;
10356
10357                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10358                if ((ArchVersion() < 6) && wback && (m == n))
10359                   return false;
10360
10361                break;
10362
10363            default:
10364                return false;
10365        }
10366
10367        Register base_reg;
10368        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10369        Register offset_reg;
10370        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10371        Register data_reg;
10372        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10373
10374        uint32_t Rn = ReadCoreReg (n, &success);
10375        if (!success)
10376            return false;
10377
10378        uint32_t Rm = ReadCoreReg (m, &success);
10379        if (!success)
10380            return false;
10381
10382        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10383        addr_t offset_addr;
10384        if (add)
10385            offset_addr = Rn + Rm;
10386        else
10387            offset_addr = Rn - Rm;
10388
10389        // address = if index then offset_addr else R[n];
10390        addr_t address;
10391        if (index)
10392            address = offset_addr;
10393        else
10394            address = Rn;
10395                          // MemA[address,4] = R[t];
10396        uint32_t Rt = ReadCoreReg (t, &success);
10397        if (!success)
10398            return false;
10399
10400        EmulateInstruction::Context context;
10401        context.type = eContextRegisterStore;
10402        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10403
10404        const uint32_t addr_byte_size = GetAddressByteSize();
10405
10406        if (!MemAWrite (context, address, Rt, addr_byte_size))
10407            return false;
10408
10409        // MemA[address+4,4] = R[t2];
10410        uint32_t Rt2 = ReadCoreReg (t2, &success);
10411        if (!success)
10412            return false;
10413
10414        data_reg.num = dwarf_r0 + t2;
10415
10416        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10417
10418        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10419            return false;
10420
10421        // if wback then R[n] = offset_addr;
10422        if (wback)
10423        {
10424            context.type = eContextAdjustBaseRegister;
10425            context.SetAddress (offset_addr);
10426
10427            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10428                return false;
10429
10430        }
10431    }
10432    return true;
10433}
10434
10435// A8.6.319 VLDM
10436// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10437// an ARM core register.
10438bool
10439EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10440{
10441#if 0
10442    if ConditionPassed() then
10443        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10444        address = if add then R[n] else R[n]-imm32;
10445        if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10446        for r = 0 to regs-1
10447            if single_regs then
10448                S[d+r] = MemA[address,4]; address = address+4;
10449            else
10450                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10451                // Combine the word-aligned words in the correct order for current endianness.
10452                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10453#endif
10454
10455    bool success = false;
10456
10457    if (ConditionPassed(opcode))
10458    {
10459        bool single_regs;
10460        bool add;
10461        bool wback;
10462        uint32_t d;
10463        uint32_t n;
10464        uint32_t imm32;
10465        uint32_t regs;
10466
10467        switch (encoding)
10468        {
10469            case eEncodingT1:
10470            case eEncodingA1:
10471                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10472                // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10473                // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10474                // if P == U && W == ‘1’ then UNDEFINED;
10475                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10476                    return false;
10477
10478                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10479                // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10480                single_regs = false;
10481                add = BitIsSet (opcode, 23);
10482                wback = BitIsSet (opcode, 21);
10483
10484                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10485                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10486                n = Bits32 (opcode, 19, 16);
10487                imm32 = Bits32 (opcode, 7, 0) << 2;
10488
10489                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FLDMX”.
10490                regs = Bits32 (opcode, 7, 0) / 2;
10491
10492                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10493                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10494                    return false;
10495
10496                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10497                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10498                    return false;
10499
10500                break;
10501
10502            case eEncodingT2:
10503            case eEncodingA2:
10504                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10505                // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10506                // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10507                // if P == U && W == ‘1’ then UNDEFINED;
10508                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10509                    return false;
10510
10511                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10512                // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10513                single_regs = true;
10514                add = BitIsSet (opcode, 23);
10515                wback = BitIsSet (opcode, 21);
10516                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10517                n = Bits32 (opcode, 19, 16);
10518
10519                // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10520                imm32 = Bits32 (opcode, 7, 0) << 2;
10521                regs = Bits32 (opcode, 7, 0);
10522
10523                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10524                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10525                    return false;
10526
10527                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10528                if ((regs == 0) || ((d + regs) > 32))
10529                    return false;
10530                break;
10531
10532            default:
10533                return false;
10534        }
10535
10536        Register base_reg;
10537        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10538
10539        uint32_t Rn = ReadCoreReg (n, &success);
10540        if (!success)
10541            return false;
10542
10543        // address = if add then R[n] else R[n]-imm32;
10544        addr_t address;
10545        if (add)
10546            address = Rn;
10547        else
10548            address = Rn - imm32;
10549
10550        // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10551        EmulateInstruction::Context context;
10552
10553        if (wback)
10554        {
10555            uint32_t value;
10556            if (add)
10557                value = Rn + imm32;
10558            else
10559                value = Rn - imm32;
10560
10561            context.type = eContextAdjustBaseRegister;
10562            context.SetImmediateSigned (value - Rn);
10563            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10564                return false;
10565
10566        }
10567
10568        const uint32_t addr_byte_size = GetAddressByteSize();
10569        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10570
10571        context.type = eContextRegisterLoad;
10572
10573        // for r = 0 to regs-1
10574        for (uint32_t r = 0; r < regs; ++r)
10575        {
10576            if (single_regs)
10577            {
10578                // S[d+r] = MemA[address,4]; address = address+4;
10579                context.SetRegisterPlusOffset (base_reg, address - Rn);
10580
10581                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10582                if (!success)
10583                    return false;
10584
10585                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10586                    return false;
10587
10588                address = address + 4;
10589            }
10590            else
10591            {
10592                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10593                context.SetRegisterPlusOffset (base_reg, address - Rn);
10594                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10595                if (!success)
10596                    return false;
10597
10598                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10599                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10600                if (!success)
10601                    return false;
10602
10603                address = address + 8;
10604                // // Combine the word-aligned words in the correct order for current endianness.
10605                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10606                uint64_t data;
10607                if (m_byte_order == eByteOrderBig)
10608                {
10609                    data = word1;
10610                    data = (data << 32) | word2;
10611                }
10612                else
10613                {
10614                    data = word2;
10615                    data = (data << 32) | word1;
10616                }
10617
10618                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10619                    return false;
10620            }
10621        }
10622    }
10623    return true;
10624}
10625
10626// A8.6.399 VSTM
10627// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10628// ARM core register.
10629bool
10630EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10631{
10632#if 0
10633    if ConditionPassed() then
10634        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10635        address = if add then R[n] else R[n]-imm32;
10636        if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10637        for r = 0 to regs-1
10638            if single_regs then
10639                MemA[address,4] = S[d+r]; address = address+4;
10640            else
10641                // Store as two word-aligned words in the correct order for current endianness.
10642                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10643                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10644                address = address+8;
10645#endif
10646
10647    bool success = false;
10648
10649    if (ConditionPassed (opcode))
10650    {
10651        bool single_regs;
10652        bool add;
10653        bool wback;
10654        uint32_t d;
10655        uint32_t n;
10656        uint32_t imm32;
10657        uint32_t regs;
10658
10659        switch (encoding)
10660        {
10661            case eEncodingT1:
10662            case eEncodingA1:
10663                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10664                // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10665                // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10666                // if P == U && W == ‘1’ then UNDEFINED;
10667                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10668                    return false;
10669
10670                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10671                // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10672                single_regs = false;
10673                add = BitIsSet (opcode, 23);
10674                wback = BitIsSet (opcode, 21);
10675
10676                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10677                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10678                n = Bits32 (opcode, 19, 16);
10679                imm32 = Bits32 (opcode, 7, 0) << 2;
10680
10681                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FSTMX”.
10682                regs = Bits32 (opcode, 7, 0) / 2;
10683
10684                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10685                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10686                    return false;
10687
10688                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10689                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10690                    return false;
10691
10692                break;
10693
10694            case eEncodingT2:
10695            case eEncodingA2:
10696                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10697                // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10698                // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10699                // if P == U && W == ‘1’ then UNDEFINED;
10700                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10701                    return false;
10702
10703                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10704                // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10705                single_regs = true;
10706                add = BitIsSet (opcode, 23);
10707                wback = BitIsSet (opcode, 21);
10708                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10709                n = Bits32 (opcode, 19, 16);
10710
10711                // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10712                imm32 = Bits32 (opcode, 7, 0) << 2;
10713                regs = Bits32 (opcode, 7, 0);
10714
10715                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10716                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10717                    return false;
10718
10719                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10720                if ((regs == 0) || ((d + regs) > 32))
10721                    return false;
10722
10723                break;
10724
10725            default:
10726                return false;
10727        }
10728
10729        Register base_reg;
10730        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10731
10732        uint32_t Rn = ReadCoreReg (n, &success);
10733        if (!success)
10734            return false;
10735
10736        // address = if add then R[n] else R[n]-imm32;
10737        addr_t address;
10738        if (add)
10739            address = Rn;
10740        else
10741            address = Rn - imm32;
10742
10743        EmulateInstruction::Context context;
10744        // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10745        if (wback)
10746        {
10747            uint32_t value;
10748            if (add)
10749                value = Rn + imm32;
10750            else
10751                value = Rn - imm32;
10752
10753            context.type = eContextAdjustBaseRegister;
10754            context.SetRegisterPlusOffset (base_reg, value - Rn);
10755
10756            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10757                return false;
10758        }
10759
10760        const uint32_t addr_byte_size = GetAddressByteSize();
10761        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10762
10763        context.type = eContextRegisterStore;
10764        // for r = 0 to regs-1
10765        for (int r = 0; r < regs; ++r)
10766        {
10767            Register data_reg;
10768            data_reg.SetRegister (eRegisterKindDWARF, 0);
10769            if (single_regs)
10770            {
10771                // MemA[address,4] = S[d+r]; address = address+4;
10772                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10773                if (!success)
10774                    return false;
10775
10776                data_reg.num = start_reg + d + r;
10777                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10778                if (!MemAWrite (context, address, data, addr_byte_size))
10779                    return false;
10780
10781                address = address + 4;
10782            }
10783            else
10784            {
10785                // // Store as two word-aligned words in the correct order for current endianness.
10786                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10787                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10788                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10789                if (!success)
10790                    return false;
10791
10792                data_reg.num = start_reg + d + r;
10793
10794                if (m_byte_order == eByteOrderBig)
10795                {
10796                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10797                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10798                        return false;
10799
10800                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10801                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10802                        return false;
10803                }
10804                else
10805                {
10806                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10807                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10808                        return false;
10809
10810                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10811                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10812                        return false;
10813                }
10814                // address = address+8;
10815                address = address + 8;
10816            }
10817        }
10818    }
10819    return true;
10820}
10821
10822// A8.6.320
10823// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10824// an optional offset.
10825bool
10826EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10827{
10828#if 0
10829    if ConditionPassed() then
10830        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10831        base = if n == 15 then Align(PC,4) else R[n];
10832        address = if add then (base + imm32) else (base - imm32);
10833        if single_reg then
10834            S[d] = MemA[address,4];
10835        else
10836            word1 = MemA[address,4]; word2 = MemA[address+4,4];
10837            // Combine the word-aligned words in the correct order for current endianness.
10838            D[d] = if BigEndian() then word1:word2 else word2:word1;
10839#endif
10840
10841    bool success = false;
10842
10843    if (ConditionPassed (opcode))
10844    {
10845        bool single_reg;
10846        bool add;
10847        uint32_t imm32;
10848        uint32_t d;
10849        uint32_t n;
10850
10851        switch (encoding)
10852        {
10853            case eEncodingT1:
10854            case eEncodingA1:
10855                // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10856                single_reg = false;
10857                add = BitIsSet (opcode, 23);
10858                imm32 = Bits32 (opcode, 7, 0) << 2;
10859
10860                // d = UInt(D:Vd); n = UInt(Rn);
10861                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10862                n = Bits32 (opcode, 19, 16);
10863
10864                break;
10865
10866            case eEncodingT2:
10867            case eEncodingA2:
10868                // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10869                single_reg = true;
10870                add = BitIsSet (opcode, 23);
10871                imm32 = Bits32 (opcode, 7, 0) << 2;
10872
10873                // d = UInt(Vd:D); n = UInt(Rn);
10874                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10875                n = Bits32 (opcode, 19, 16);
10876
10877                break;
10878
10879            default:
10880                return false;
10881        }
10882        Register base_reg;
10883        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10884
10885        uint32_t Rn = ReadCoreReg (n, &success);
10886        if (!success)
10887            return false;
10888
10889        // base = if n == 15 then Align(PC,4) else R[n];
10890        uint32_t base;
10891        if (n == 15)
10892            base = AlignPC (Rn);
10893        else
10894            base = Rn;
10895
10896        // address = if add then (base + imm32) else (base - imm32);
10897        addr_t address;
10898        if (add)
10899            address = base + imm32;
10900        else
10901            address = base - imm32;
10902
10903        const uint32_t addr_byte_size = GetAddressByteSize();
10904        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
10905
10906        EmulateInstruction::Context context;
10907        context.type = eContextRegisterLoad;
10908        context.SetRegisterPlusOffset (base_reg, address - base);
10909
10910        if (single_reg)
10911        {
10912            // S[d] = MemA[address,4];
10913            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10914            if (!success)
10915                return false;
10916
10917            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
10918                return false;
10919        }
10920        else
10921        {
10922            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
10923            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10924            if (!success)
10925                return false;
10926
10927            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
10928            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10929            if (!success)
10930                return false;
10931            // // Combine the word-aligned words in the correct order for current endianness.
10932            // D[d] = if BigEndian() then word1:word2 else word2:word1;
10933            uint64_t data64;
10934            if (m_byte_order == eByteOrderBig)
10935            {
10936                data64 = word1;
10937                data64 = (data64 << 32) | word2;
10938            }
10939            else
10940            {
10941                data64 = word2;
10942                data64 = (data64 << 32) | word1;
10943            }
10944
10945            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
10946                return false;
10947        }
10948    }
10949    return true;
10950}
10951
10952// A8.6.400 VSTR
10953// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
10954// optional offset.
10955bool
10956EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
10957{
10958#if 0
10959    if ConditionPassed() then
10960        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10961        address = if add then (R[n] + imm32) else (R[n] - imm32);
10962        if single_reg then
10963            MemA[address,4] = S[d];
10964        else
10965            // Store as two word-aligned words in the correct order for current endianness.
10966            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
10967            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
10968#endif
10969
10970    bool success = false;
10971
10972    if (ConditionPassed (opcode))
10973    {
10974        bool single_reg;
10975        bool add;
10976        uint32_t imm32;
10977        uint32_t d;
10978        uint32_t n;
10979
10980        switch (encoding)
10981        {
10982            case eEncodingT1:
10983            case eEncodingA1:
10984                // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10985                single_reg = false;
10986                add = BitIsSet (opcode, 23);
10987                imm32 = Bits32 (opcode, 7, 0) << 2;
10988
10989                // d = UInt(D:Vd); n = UInt(Rn);
10990                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10991                n = Bits32 (opcode, 19, 16);
10992
10993                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
10994                if ((n == 15) && (CurrentInstrSet() != eModeARM))
10995                    return false;
10996
10997                break;
10998
10999            case eEncodingT2:
11000            case eEncodingA2:
11001                // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
11002                single_reg = true;
11003                add = BitIsSet (opcode, 23);
11004                imm32 = Bits32 (opcode, 7, 0) << 2;
11005
11006                // d = UInt(Vd:D); n = UInt(Rn);
11007                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11008                n = Bits32 (opcode, 19, 16);
11009
11010                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11011                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11012                    return false;
11013
11014                break;
11015
11016            default:
11017                return false;
11018        }
11019
11020        Register base_reg;
11021        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11022
11023        uint32_t Rn = ReadCoreReg (n, &success);
11024        if (!success)
11025            return false;
11026
11027        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11028        addr_t address;
11029        if (add)
11030            address = Rn + imm32;
11031        else
11032            address = Rn - imm32;
11033
11034        const uint32_t addr_byte_size = GetAddressByteSize();
11035        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11036
11037        Register data_reg;
11038        data_reg.SetRegister (eRegisterKindDWARF, start_reg + d);
11039        EmulateInstruction::Context context;
11040        context.type = eContextRegisterStore;
11041        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11042
11043        if (single_reg)
11044        {
11045            // MemA[address,4] = S[d];
11046            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11047            if (!success)
11048                return false;
11049
11050            if (!MemAWrite (context, address, data, addr_byte_size))
11051                return false;
11052        }
11053        else
11054        {
11055            // // Store as two word-aligned words in the correct order for current endianness.
11056            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11057            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11058            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11059            if (!success)
11060                return false;
11061
11062            if (m_byte_order == eByteOrderBig)
11063            {
11064                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11065                    return false;
11066
11067                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11068                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11069                    return false;
11070            }
11071            else
11072            {
11073                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11074                    return false;
11075
11076                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11077                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11078                    return false;
11079            }
11080        }
11081    }
11082    return true;
11083}
11084
11085// A8.6.307 VLDI1 (multiple single elements)
11086// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11087// element of each register is loaded.
11088bool
11089EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11090{
11091#if 0
11092    if ConditionPassed() then
11093        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11094        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11095        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11096        for r = 0 to regs-1
11097            for e = 0 to elements-1
11098                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11099                address = address + ebytes;
11100#endif
11101
11102    bool success = false;
11103
11104    if (ConditionPassed (opcode))
11105    {
11106        uint32_t regs;
11107        uint32_t alignment;
11108        uint32_t ebytes;
11109        uint32_t esize;
11110        uint32_t elements;
11111        uint32_t d;
11112        uint32_t n;
11113        uint32_t m;
11114        bool wback;
11115        bool register_index;
11116
11117        switch (encoding)
11118        {
11119            case eEncodingT1:
11120            case eEncodingA1:
11121            {
11122                // case type of
11123                    // when ‘0111’
11124                        // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11125                    // when ‘1010’
11126                        // regs = 2; if align == ‘11’ then UNDEFINED;
11127                    // when ‘0110’
11128                        // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11129                    // when ‘0010’
11130                        // regs = 4;
11131                    // otherwise
11132                        // SEE “Related encodings”;
11133                uint32_t type = Bits32 (opcode, 11, 8);
11134                uint32_t align = Bits32 (opcode, 5, 4);
11135                if (type == 7) // '0111'
11136                {
11137                    regs = 1;
11138                    if (BitIsSet (align, 1))
11139                        return false;
11140                }
11141                else if (type == 10) // '1010'
11142                {
11143                    regs = 2;
11144                    if (align == 3)
11145                        return false;
11146
11147                }
11148                else if (type == 6) // '0110'
11149                {
11150                    regs = 3;
11151                    if (BitIsSet (align, 1))
11152                        return false;
11153                }
11154                else if (type == 2) // '0010'
11155                {
11156                    regs = 4;
11157                }
11158                else
11159                    return false;
11160
11161                // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11162                if (align == 0)
11163                    alignment = 1;
11164                else
11165                    alignment = 4 << align;
11166
11167                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11168                ebytes = 1 << Bits32 (opcode, 7, 6);
11169                esize = 8 * ebytes;
11170                elements = 8 / ebytes;
11171
11172                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11173                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11174                n = Bits32 (opcode, 19, 15);
11175                m = Bits32 (opcode, 3, 0);
11176
11177                // wback = (m != 15); register_index = (m != 15 && m != 13);
11178                wback = (m != 15);
11179                register_index = ((m != 15) && (m != 13));
11180
11181                // if d+regs > 32 then UNPREDICTABLE;
11182                if ((d + regs) > 32)
11183                    return false;
11184            }
11185                break;
11186
11187            default:
11188                return false;
11189        }
11190
11191        Register base_reg;
11192        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11193
11194        uint32_t Rn = ReadCoreReg (n, &success);
11195        if (!success)
11196            return false;
11197
11198        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11199        addr_t address = Rn;
11200        if ((address % alignment) != 0)
11201            return false;
11202
11203        EmulateInstruction::Context context;
11204        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11205        if (wback)
11206        {
11207            uint32_t Rm = ReadCoreReg (m, &success);
11208            if (!success)
11209                return false;
11210
11211            uint32_t offset;
11212            if (register_index)
11213                offset = Rm;
11214            else
11215                offset = 8 * regs;
11216
11217            uint32_t value = Rn + offset;
11218            context.type = eContextAdjustBaseRegister;
11219            context.SetRegisterPlusOffset (base_reg, offset);
11220
11221            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11222                return false;
11223
11224        }
11225
11226        // for r = 0 to regs-1
11227        for (int r = 0; r < regs; ++r)
11228        {
11229            // for e = 0 to elements-1
11230            uint64_t assembled_data = 0;
11231            for (int e = 0; e < elements; ++e)
11232            {
11233                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11234                context.type = eContextRegisterLoad;
11235                context.SetRegisterPlusOffset (base_reg, address - Rn);
11236                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11237                if (!success)
11238                    return false;
11239
11240                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11241
11242                // address = address + ebytes;
11243                address = address + ebytes;
11244            }
11245            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11246                return false;
11247        }
11248    }
11249    return true;
11250}
11251
11252// A8.6.308 VLD1 (single element to one lane)
11253//
11254bool
11255EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11256{
11257#if 0
11258    if ConditionPassed() then
11259        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11260        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11261        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11262        Elem[D[d],index,esize] = MemU[address,ebytes];
11263#endif
11264
11265    bool success = false;
11266
11267    if (ConditionPassed (opcode))
11268    {
11269        uint32_t ebytes;
11270        uint32_t esize;
11271        uint32_t index;
11272        uint32_t alignment;
11273        uint32_t d;
11274        uint32_t n;
11275        uint32_t m;
11276        bool wback;
11277        bool register_index;
11278
11279        switch (encoding)
11280        {
11281            case eEncodingT1:
11282            case eEncodingA1:
11283            {
11284                uint32_t size = Bits32 (opcode, 11, 10);
11285                uint32_t index_align = Bits32 (opcode, 7, 4);
11286                // if size == ‘11’ then SEE VLD1 (single element to all lanes);
11287                if (size == 3)
11288                   return EmulateVLD1SingleAll (opcode, encoding);
11289                // case size of
11290                if (size == 0) // when '00'
11291                {
11292                    // if index_align<0> != ‘0’ then UNDEFINED;
11293                    if (BitIsClear (index_align, 0))
11294                        return false;
11295
11296                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11297                    ebytes = 1;
11298                    esize = 8;
11299                    index = Bits32 (index_align, 3, 1);
11300                    alignment = 1;
11301                }
11302                else if (size == 1) // when ‘01’
11303                {
11304                    // if index_align<1> != ‘0’ then UNDEFINED;
11305                    if (BitIsClear (index_align, 1))
11306                        return false;
11307
11308                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11309                    ebytes = 2;
11310                    esize = 16;
11311                    index = Bits32 (index_align, 3, 2);
11312
11313                    // alignment = if index_align<0> == ‘0’ then 1 else 2;
11314                    if (BitIsClear (index_align, 0))
11315                        alignment = 1;
11316                    else
11317                        alignment = 2;
11318                }
11319                else if (size == 2) // when ‘10’
11320                {
11321                    // if index_align<2> != ‘0’ then UNDEFINED;
11322                    if (BitIsClear (index_align, 2))
11323                        return false;
11324
11325                    // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11326                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11327                        return false;
11328
11329                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11330                    ebytes = 4;
11331                    esize = 32;
11332                    index = Bit32 (index_align, 3);
11333
11334                    // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11335                    if (Bits32 (index_align, 1, 0) == 0)
11336                        alignment = 1;
11337                    else
11338                        alignment = 4;
11339                }
11340                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11341                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11342                n = Bits32 (opcode, 19, 16);
11343                m = Bits32 (opcode, 3, 0);
11344
11345                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11346                wback = (m != 15);
11347                register_index = ((m != 15) && (m != 13));
11348
11349                if (n == 15)
11350                    return false;
11351
11352            }
11353                break;
11354
11355            default:
11356                return false;
11357        }
11358
11359        Register base_reg;
11360        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11361
11362        uint32_t Rn = ReadCoreReg (n, &success);
11363        if (!success)
11364            return false;
11365
11366        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11367        addr_t address = Rn;
11368        if ((address % alignment) != 0)
11369            return false;
11370
11371        EmulateInstruction::Context context;
11372        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11373        if (wback)
11374        {
11375            uint32_t Rm = ReadCoreReg (m, &success);
11376            if (!success)
11377                return false;
11378
11379            uint32_t offset;
11380            if (register_index)
11381                offset = Rm;
11382            else
11383                offset = ebytes;
11384
11385            uint32_t value = Rn + offset;
11386
11387            context.type = eContextAdjustBaseRegister;
11388            context.SetRegisterPlusOffset (base_reg, offset);
11389
11390            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11391                return false;
11392        }
11393
11394        // Elem[D[d],index,esize] = MemU[address,ebytes];
11395        uint32_t element = MemURead (context, address, esize, 0, &success);
11396        if (!success)
11397            return false;
11398
11399        element = element << (index * esize);
11400
11401        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11402        if (!success)
11403            return false;
11404
11405        uint64_t all_ones = -1;
11406        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11407                                                          // at element & to the right of element.
11408        if (index > 0)
11409            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11410                                                                     // now mask should be 0's where element goes & 1's
11411                                                                     // everywhere else.
11412
11413        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11414        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11415
11416        context.type = eContextRegisterLoad;
11417        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11418            return false;
11419    }
11420    return true;
11421}
11422
11423// A8.6.391 VST1 (multiple single elements)
11424// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11425// interleaving.  Every element of each register is stored.
11426bool
11427EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11428{
11429#if 0
11430    if ConditionPassed() then
11431        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11432        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11433        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11434        for r = 0 to regs-1
11435            for e = 0 to elements-1
11436                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11437                address = address + ebytes;
11438#endif
11439
11440    bool success = false;
11441
11442    if (ConditionPassed (opcode))
11443    {
11444        uint32_t regs;
11445        uint32_t alignment;
11446        uint32_t ebytes;
11447        uint32_t esize;
11448        uint32_t elements;
11449        uint32_t d;
11450        uint32_t n;
11451        uint32_t m;
11452        bool wback;
11453        bool register_index;
11454
11455        switch (encoding)
11456        {
11457            case eEncodingT1:
11458            case eEncodingA1:
11459            {
11460                uint32_t type = Bits32 (opcode, 11, 8);
11461                uint32_t align = Bits32 (opcode, 5, 4);
11462
11463                // case type of
11464                if (type == 7)    // when ‘0111’
11465                {
11466                    // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11467                    regs = 1;
11468                    if (BitIsSet (align, 1))
11469                        return false;
11470                }
11471                else if (type == 10) // when ‘1010’
11472                {
11473                    // regs = 2; if align == ‘11’ then UNDEFINED;
11474                    regs = 2;
11475                    if (align == 3)
11476                        return false;
11477                }
11478                else if (type == 6) // when ‘0110’
11479                {
11480                    // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11481                    regs = 3;
11482                    if (BitIsSet (align, 1))
11483                        return false;
11484                }
11485                else if (type == 2) // when ‘0010’
11486                    // regs = 4;
11487                    regs = 4;
11488                else // otherwise
11489                    // SEE “Related encodings”;
11490                    return false;
11491
11492                // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11493                if (align == 0)
11494                    alignment = 0;
11495                else
11496                    alignment = 4 << align;
11497
11498                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11499                ebytes = 1 << Bits32 (opcode,7, 6);
11500                esize = 8 * ebytes;
11501                elements = 8 / ebytes;
11502
11503                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11504                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11505                n = Bits32 (opcode, 19, 16);
11506                m = Bits32 (opcode, 3, 0);
11507
11508                // wback = (m != 15); register_index = (m != 15 && m != 13);
11509                wback = (m != 15);
11510                register_index = ((m != 15) && (m != 13));
11511
11512                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11513                if ((d + regs) > 32)
11514                    return false;
11515
11516                if (n == 15)
11517                    return false;
11518
11519            }
11520                break;
11521
11522            default:
11523                return false;
11524        }
11525
11526        Register base_reg;
11527        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11528
11529        uint32_t Rn = ReadCoreReg (n, &success);
11530        if (!success)
11531            return false;
11532
11533        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11534        addr_t address = Rn;
11535        if ((address % alignment) != 0)
11536            return false;
11537
11538        EmulateInstruction::Context context;
11539        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11540        if (wback)
11541        {
11542            uint32_t Rm = ReadCoreReg (m, &success);
11543            if (!success)
11544                return false;
11545
11546            uint32_t offset;
11547            if (register_index)
11548                offset = Rm;
11549            else
11550                offset = 8 * regs;
11551
11552            context.type = eContextAdjustBaseRegister;
11553            context.SetRegisterPlusOffset (base_reg, offset);
11554
11555            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11556                return false;
11557        }
11558
11559        context.type = eContextRegisterStore;
11560        Register data_reg;
11561        data_reg.SetRegister (eRegisterKindDWARF, 0);
11562        // for r = 0 to regs-1
11563        for (int r = 0; r < regs; ++r)
11564        {
11565            data_reg.num = dwarf_d0 + d + r;
11566            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11567            if (!success)
11568                return false;
11569
11570             // for e = 0 to elements-1
11571            for (int e = 0; e < elements; ++e)
11572            {
11573                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11574                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11575
11576                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11577                if (!MemUWrite (context, address, word, ebytes))
11578                    return false;
11579
11580                // address = address + ebytes;
11581                address = address + ebytes;
11582            }
11583        }
11584    }
11585    return true;
11586}
11587
11588// A8.6.392 VST1 (single element from one lane)
11589// This instruction stores one element to memory from one element of a register.
11590bool
11591EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11592{
11593#if 0
11594    if ConditionPassed() then
11595        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11596        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11597        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11598        MemU[address,ebytes] = Elem[D[d],index,esize];
11599#endif
11600
11601    bool success = false;
11602
11603    if (ConditionPassed (opcode))
11604    {
11605        uint32_t ebytes;
11606        uint32_t esize;
11607        uint32_t index;
11608        uint32_t alignment;
11609        uint32_t d;
11610        uint32_t n;
11611        uint32_t m;
11612        bool wback;
11613        bool register_index;
11614
11615        switch (encoding)
11616        {
11617            case eEncodingT1:
11618            case eEncodingA1:
11619            {
11620                uint32_t size = Bits32 (opcode, 11, 10);
11621                uint32_t index_align = Bits32 (opcode, 7, 4);
11622
11623                // if size == ‘11’ then UNDEFINED;
11624                if (size == 3)
11625                    return false;
11626
11627                // case size of
11628                if (size == 0) // when ‘00’
11629                {
11630                    // if index_align<0> != ‘0’ then UNDEFINED;
11631                    if (BitIsClear (index_align, 0))
11632                        return false;
11633                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11634                    ebytes = 1;
11635                    esize = 8;
11636                    index = Bits32 (index_align, 3, 1);
11637                    alignment = 1;
11638                }
11639                else if (size == 1) // when ‘01’
11640                {
11641                    // if index_align<1> != ‘0’ then UNDEFINED;
11642                    if (BitIsClear (index_align, 1))
11643                        return false;
11644
11645                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11646                    ebytes = 2;
11647                    esize = 16;
11648                    index = Bits32 (index_align, 3, 2);
11649
11650                    // alignment = if index_align<0> == ‘0’ then 1 else 2;
11651                    if (BitIsClear (index_align, 0))
11652                        alignment = 1;
11653                    else
11654                        alignment = 2;
11655                }
11656                else if (size == 2) // when ‘10’
11657                {
11658                    // if index_align<2> != ‘0’ then UNDEFINED;
11659                    if (BitIsClear (index_align, 2))
11660                        return false;
11661
11662                    // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11663                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11664                        return false;
11665
11666                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11667                    ebytes = 4;
11668                    esize = 32;
11669                    index = Bit32 (index_align, 3);
11670
11671                    // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11672                    if (Bits32 (index_align, 1, 0) == 0)
11673                        alignment = 1;
11674                    else
11675                        alignment = 4;
11676                }
11677                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11678                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11679                n = Bits32 (opcode, 19, 16);
11680                m = Bits32 (opcode, 3, 0);
11681
11682                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11683                wback = (m != 15);
11684                register_index = ((m != 15) && (m != 13));
11685
11686                if (n == 15)
11687                    return false;
11688            }
11689                break;
11690
11691            default:
11692                return false;
11693        }
11694
11695        Register base_reg;
11696        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11697
11698        uint32_t Rn = ReadCoreReg (n, &success);
11699        if (!success)
11700            return false;
11701
11702        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11703        addr_t address = Rn;
11704        if ((address % alignment) != 0)
11705            return false;
11706
11707        EmulateInstruction::Context context;
11708        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11709        if (wback)
11710        {
11711            uint32_t Rm = ReadCoreReg (m, &success);
11712            if (!success)
11713                return false;
11714
11715            uint32_t offset;
11716            if (register_index)
11717                offset = Rm;
11718            else
11719                offset = ebytes;
11720
11721            context.type = eContextAdjustBaseRegister;
11722            context.SetRegisterPlusOffset (base_reg, offset);
11723
11724            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11725                return false;
11726        }
11727
11728        // MemU[address,ebytes] = Elem[D[d],index,esize];
11729        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11730        if (!success)
11731            return false;
11732
11733        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11734
11735        Register data_reg;
11736        data_reg.SetRegister (eRegisterKindDWARF, dwarf_d0 + d);
11737        context.type = eContextRegisterStore;
11738        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11739
11740        if (!MemUWrite (context, address, word, ebytes))
11741            return false;
11742    }
11743    return true;
11744}
11745
11746// A8.6.309 VLD1 (single element to all lanes)
11747// This instruction loads one element from memory into every element of one or two vectors.
11748bool
11749EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11750{
11751#if 0
11752    if ConditionPassed() then
11753        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11754        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11755        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11756        replicated_element = Replicate(MemU[address,ebytes], elements);
11757        for r = 0 to regs-1
11758            D[d+r] = replicated_element;
11759#endif
11760
11761    bool success = false;
11762
11763    if (ConditionPassed (opcode))
11764    {
11765        uint32_t ebytes;
11766        uint32_t elements;
11767        uint32_t regs;
11768        uint32_t alignment;
11769        uint32_t d;
11770        uint32_t n;
11771        uint32_t m;
11772        bool wback;
11773        bool register_index;
11774
11775        switch (encoding)
11776        {
11777            case eEncodingT1:
11778            case eEncodingA1:
11779            {
11780                //if size == ‘11’ || (size == ‘00’ && a == ‘1’) then UNDEFINED;
11781                uint32_t size = Bits32 (opcode, 7, 6);
11782                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11783                    return false;
11784
11785                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == ‘0’ then 1 else 2;
11786                ebytes = 1 << size;
11787                elements = 8 / ebytes;
11788                if (BitIsClear (opcode, 5))
11789                    regs = 1;
11790                else
11791                    regs = 2;
11792
11793                //alignment = if a == ‘0’ then 1 else ebytes;
11794                if (BitIsClear (opcode, 4))
11795                    alignment = 1;
11796                else
11797                    alignment = ebytes;
11798
11799                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11800                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11801                n = Bits32 (opcode, 19, 16);
11802                m = Bits32 (opcode, 3, 0);
11803
11804                //wback = (m != 15); register_index = (m != 15 && m != 13);
11805                wback = (m != 15);
11806                register_index = ((m != 15) && (m != 13));
11807
11808                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11809                if ((d + regs) > 32)
11810                    return false;
11811
11812                if (n == 15)
11813                    return false;
11814            }
11815                break;
11816
11817            default:
11818                break;
11819        }
11820
11821        Register base_reg;
11822        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
11823
11824        uint32_t Rn = ReadCoreReg (n, &success);
11825        if (!success)
11826            return false;
11827
11828        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11829        addr_t address = Rn;
11830        if ((address % alignment) != 0)
11831            return false;
11832
11833        EmulateInstruction::Context context;
11834        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11835        if (wback)
11836        {
11837            uint32_t Rm = ReadCoreReg (m, &success);
11838            if (!success)
11839                return false;
11840
11841            uint32_t offset;
11842            if (register_index)
11843                offset = Rm;
11844            else
11845                offset = ebytes;
11846
11847            context.type = eContextAdjustBaseRegister;
11848            context.SetRegisterPlusOffset (base_reg, offset);
11849
11850            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11851                return false;
11852        }
11853
11854        // replicated_element = Replicate(MemU[address,ebytes], elements);
11855
11856        context.type = eContextRegisterLoad;
11857        uint64_t word = MemURead (context, address, ebytes, 0, &success);
11858        if (!success)
11859            return false;
11860
11861        uint64_t replicated_element;
11862        uint32_t esize = ebytes * 8;
11863        for (int e = 0; e < elements; ++e)
11864            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
11865
11866        // for r = 0 to regs-1
11867        for (int r = 0; r < regs; ++r)
11868        {
11869            // D[d+r] = replicated_element;
11870            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
11871                return false;
11872        }
11873    }
11874    return true;
11875}
11876
11877// B6.2.13 SUBS PC, LR and related instructions
11878//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
11879// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
11880bool
11881EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
11882{
11883#if 0
11884    if ConditionPassed() then
11885        EncodingSpecificOperations();
11886        if CurrentInstrSet() == InstrSet_ThumbEE then
11887            UNPREDICTABLE;
11888        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
11889        case opcode of
11890            when ‘0000’ result = R[n] AND operand2; // AND
11891            when ‘0001result = R[n] EOR operand2; // EOR
11892            when ‘0010’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB
11893            when ‘0011’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB
11894            when ‘0100’ (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD
11895            when ‘0101’ (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
11896            when ‘0110’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
11897            when ‘0111’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
11898            when1100result = R[n] OR operand2; // ORR
11899            when1101result = operand2; // MOV
11900            when1110result = R[n] AND NOT(operand2); // BIC
11901            when1111result = NOT(operand2); // MVN
11902        CPSRWriteByInstr(SPSR[], ‘1111’, TRUE);
11903        BranchWritePC(result);
11904#endif
11905
11906    bool success = false;
11907
11908    if (ConditionPassed (opcode))
11909    {
11910        uint32_t n;
11911        uint32_t m;
11912        uint32_t imm32;
11913        bool register_form;
11914        ARM_ShifterType shift_t;
11915        uint32_t shift_n;
11916        uint32_t code;
11917
11918        switch (encoding)
11919        {
11920            case eEncodingT1:
11921                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
11922                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = ‘0010’; // = SUB
11923                n = 14;
11924                imm32 = Bits32 (opcode, 7, 0);
11925                register_form = false;
11926                code = 2;
11927
11928                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
11929                if (InITBlock() && !LastInITBlock())
11930                    return false;
11931
11932                break;
11933
11934            case eEncodingA1:
11935                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
11936                n = Bits32 (opcode, 19, 16);
11937                imm32 = ARMExpandImm (opcode);
11938                register_form = false;
11939                code = Bits32 (opcode, 24, 21);
11940
11941                break;
11942
11943            case eEncodingA2:
11944                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
11945                n = Bits32 (opcode, 19, 16);
11946                m = Bits32 (opcode, 3, 0);
11947                register_form = true;
11948
11949                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
11950                shift_n = DecodeImmShiftARM (opcode, shift_t);
11951
11952                break;
11953
11954            default:
11955                return false;
11956        }
11957
11958        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
11959        uint32_t operand2;
11960        if (register_form)
11961        {
11962            uint32_t Rm = ReadCoreReg (m, &success);
11963            if (!success)
11964                return false;
11965
11966            operand2 = Shift (Rm, shift_t, shift_n, APSR_C);
11967
11968        }
11969        else
11970        {
11971            operand2 = imm32;
11972        }
11973
11974        uint32_t Rn = ReadCoreReg (n, &success);
11975        if (!success)
11976            return false;
11977
11978        AddWithCarryResult result;
11979
11980        // case opcode of
11981        switch (code)
11982        {
11983            case 0: // when ‘0000’
11984                // result = R[n] AND operand2; // AND
11985                result.result = Rn & operand2;
11986                break;
11987
11988            case 1: // when ‘0001’
11989                // result = R[n] EOR operand2; // EOR
11990                result.result = Rn ^ operand2;
11991                break;
11992
11993            case 2: // when ‘0010’
11994                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB
11995                result = AddWithCarry (Rn, ~(operand2), 1);
11996                break;
11997
11998            case 3: // when ‘0011’
11999                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB
12000                result = AddWithCarry (~(Rn), operand2, 1);
12001                break;
12002
12003            case 4: // when ‘0100’
12004                // (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD
12005                result = AddWithCarry (Rn, operand2, 0);
12006                break;
12007
12008            case 5: // when ‘0101’
12009                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12010                result = AddWithCarry (Rn, operand2, APSR_C);
12011                break;
12012
12013            case 6: // when ‘0110’
12014                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12015                result = AddWithCarry (Rn, ~(operand2), APSR_C);
12016                break;
12017
12018            case 7: // when ‘0111’
12019                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12020                result = AddWithCarry (~(Rn), operand2, APSR_C);
12021                break;
12022
12023            case 10: // when ‘1100’
12024                // result = R[n] OR operand2; // ORR
12025                result.result = Rn | operand2;
12026                break;
12027
12028            case 11: // when ‘1101’
12029                // result = operand2; // MOV
12030                result.result = operand2;
12031                break;
12032
12033            case 12: // when ‘1110’
12034                // result = R[n] AND NOT(operand2); // BIC
12035                result.result = Rn & ~(operand2);
12036                break;
12037
12038            case 15: // when ‘1111’
12039                // result = NOT(operand2); // MVN
12040                result.result = ~(operand2);
12041                break;
12042
12043            default:
12044                return false;
12045        }
12046        // CPSRWriteByInstr(SPSR[], ‘1111’, TRUE);
12047
12048        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12049        // the best.
12050        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12051        if (!success)
12052            return false;
12053
12054        CPSRWriteByInstr (spsr, 15, true);
12055
12056        // BranchWritePC(result);
12057        EmulateInstruction::Context context;
12058        context.type = eContextAdjustPC;
12059        context.SetImmediate (result.result);
12060
12061        BranchWritePC (context, result.result);
12062    }
12063    return true;
12064}
12065
12066EmulateInstructionARM::ARMOpcode*
12067EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
12068{
12069    static ARMOpcode
12070    g_arm_opcodes[] =
12071    {
12072        //----------------------------------------------------------------------
12073        // Prologue instructions
12074        //----------------------------------------------------------------------
12075
12076        // push register(s)
12077        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12078        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12079
12080        // set r7 to point to a stack offset
12081        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12082        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12083        // copy the stack pointer to ip
12084        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12085        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12086        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12087
12088        // adjust the stack pointer
12089        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12090        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12091
12092        // push one register
12093        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12094        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12095
12096        // vector push consecutive extension register(s)
12097        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12098        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12099
12100        //----------------------------------------------------------------------
12101        // Epilogue instructions
12102        //----------------------------------------------------------------------
12103
12104        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12105        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12106        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12107        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12108
12109        //----------------------------------------------------------------------
12110        // Supervisor Call (previously Software Interrupt)
12111        //----------------------------------------------------------------------
12112        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12113
12114        //----------------------------------------------------------------------
12115        // Branch instructions
12116        //----------------------------------------------------------------------
12117        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12118        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12119        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12120        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12121        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12122        // for example, "bx lr"
12123        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12124        // bxj
12125        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12126
12127        //----------------------------------------------------------------------
12128        // Data-processing instructions
12129        //----------------------------------------------------------------------
12130        // adc (immediate)
12131        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12132        // adc (register)
12133        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12134        // add (immediate)
12135        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12136        // add (register)
12137        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12138        // add (register-shifted register)
12139        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12140        // adr
12141        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12142        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12143        // and (immediate)
12144        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12145        // and (register)
12146        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12147        // bic (immediate)
12148        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12149        // bic (register)
12150        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12151        // eor (immediate)
12152        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12153        // eor (register)
12154        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12155        // orr (immediate)
12156        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12157        // orr (register)
12158        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12159        // rsb (immediate)
12160        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12161        // rsb (register)
12162        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12163        // rsc (immediate)
12164        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12165        // rsc (register)
12166        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12167        // sbc (immediate)
12168        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12169        // sbc (register)
12170        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12171        // sub (immediate, ARM)
12172        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12173        // sub (sp minus immediate)
12174        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12175        // sub (register)
12176        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12177        // teq (immediate)
12178        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12179        // teq (register)
12180        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12181        // tst (immediate)
12182        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12183        // tst (register)
12184        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12185
12186        // mov (immediate)
12187        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12188        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12189        // mov (register)
12190        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12191        // mvn (immediate)
12192        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12193        // mvn (register)
12194        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12195        // cmn (immediate)
12196        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12197        // cmn (register)
12198        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12199        // cmp (immediate)
12200        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12201        // cmp (register)
12202        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12203        // asr (immediate)
12204        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12205        // asr (register)
12206        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12207        // lsl (immediate)
12208        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12209        // lsl (register)
12210        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12211        // lsr (immediate)
12212        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12213        // lsr (register)
12214        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12215        // rrx is a special case encoding of ror (immediate)
12216        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12217        // ror (immediate)
12218        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12219        // ror (register)
12220        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12221        // mul
12222        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12223
12224        // subs pc, lr and related instructions
12225        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12226        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12227
12228        //----------------------------------------------------------------------
12229        // Load instructions
12230        //----------------------------------------------------------------------
12231        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12232        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12233        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12234        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12235        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12236        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12237        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12238        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12239        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12240        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12241        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12242        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12243        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12244        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12245        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12246        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12247        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12248        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12249        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12250        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12251        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12252        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12253        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12254        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12255        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12256
12257        //----------------------------------------------------------------------
12258        // Store instructions
12259        //----------------------------------------------------------------------
12260        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12261        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12262        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12263        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12264        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12265        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12266        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12267        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12268        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12269        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12270        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12271        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12272        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12273        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12274        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12275        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12276        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12277
12278        //----------------------------------------------------------------------
12279        // Other instructions
12280        //----------------------------------------------------------------------
12281        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12282        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12283        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12284        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12285        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12286
12287    };
12288    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12289
12290    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12291    {
12292        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
12293            return &g_arm_opcodes[i];
12294    }
12295    return NULL;
12296}
12297
12298
12299EmulateInstructionARM::ARMOpcode*
12300EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
12301{
12302
12303    static ARMOpcode
12304    g_thumb_opcodes[] =
12305    {
12306        //----------------------------------------------------------------------
12307        // Prologue instructions
12308        //----------------------------------------------------------------------
12309
12310        // push register(s)
12311        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12312        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12313        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12314
12315        // set r7 to point to a stack offset
12316        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12317        // copy the stack pointer to r7
12318        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12319        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12320        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12321
12322        // PC-relative load into register (see also EmulateADDSPRm)
12323        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12324
12325        // adjust the stack pointer
12326        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12327        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12328        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12329        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12330        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12331
12332        // vector push consecutive extension register(s)
12333        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12334        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12335
12336        //----------------------------------------------------------------------
12337        // Epilogue instructions
12338        //----------------------------------------------------------------------
12339
12340        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12341        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12342        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12343        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12344        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12345        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12346        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12347
12348        //----------------------------------------------------------------------
12349        // Supervisor Call (previously Software Interrupt)
12350        //----------------------------------------------------------------------
12351        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12352
12353        //----------------------------------------------------------------------
12354        // If Then makes up to four following instructions conditional.
12355        //----------------------------------------------------------------------
12356        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12357
12358        //----------------------------------------------------------------------
12359        // Branch instructions
12360        //----------------------------------------------------------------------
12361        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12362        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12363        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12364        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12365        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12366        // J1 == J2 == 1
12367        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12368        // J1 == J2 == 1
12369        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12370        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12371        // for example, "bx lr"
12372        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12373        // bxj
12374        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12375        // compare and branch
12376        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12377        // table branch byte
12378        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12379        // table branch halfword
12380        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12381
12382        //----------------------------------------------------------------------
12383        // Data-processing instructions
12384        //----------------------------------------------------------------------
12385        // adc (immediate)
12386        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12387        // adc (register)
12388        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12389        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12390        // add (register)
12391        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12392        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12393        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12394        // adr
12395        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12396        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12397        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12398        // and (immediate)
12399        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12400        // and (register)
12401        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12402        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12403        // bic (immediate)
12404        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12405        // bic (register)
12406        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12407        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12408        // eor (immediate)
12409        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12410        // eor (register)
12411        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12412        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12413        // orr (immediate)
12414        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12415        // orr (register)
12416        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12417        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12418        // rsb (immediate)
12419        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12420        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12421        // rsb (register)
12422        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12423        // sbc (immediate)
12424        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12425        // sbc (register)
12426        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12427        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12428        // add (immediate, Thumb)
12429        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12430        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12431        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12432        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12433        // sub (immediate, Thumb)
12434        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12435        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12436        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12437        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12438        // sub (sp minus immediate)
12439        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12440        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12441        // sub (register)
12442        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12443        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12444        // teq (immediate)
12445        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12446        // teq (register)
12447        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12448        // tst (immediate)
12449        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12450        // tst (register)
12451        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12452        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12453
12454
12455        // move from high register to high register
12456        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12457        // move from low register to low register
12458        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12459        // mov{s}<c>.w <Rd>, <Rm>
12460        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12461        // move immediate
12462        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12463        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12464        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12465        // mvn (immediate)
12466        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12467        // mvn (register)
12468        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12469        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12470        // cmn (immediate)
12471        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12472        // cmn (register)
12473        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12474        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12475        // cmp (immediate)
12476        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12477        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12478        // cmp (register) (Rn and Rm both from r0-r7)
12479        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12480        // cmp (register) (Rn and Rm not both from r0-r7)
12481        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12482        // asr (immediate)
12483        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12484        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12485        // asr (register)
12486        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12487        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12488        // lsl (immediate)
12489        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12490        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12491        // lsl (register)
12492        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12493        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12494        // lsr (immediate)
12495        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12496        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12497        // lsr (register)
12498        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12499        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12500        // rrx is a special case encoding of ror (immediate)
12501        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12502        // ror (immediate)
12503        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12504        // ror (register)
12505        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12506        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12507        // mul
12508        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12509        // mul
12510        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12511
12512        // subs pc, lr and related instructions
12513        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12514
12515        //----------------------------------------------------------------------
12516        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12517        // otherwise the wrong instructions will be selected.
12518        //----------------------------------------------------------------------
12519
12520        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12521        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12522
12523        //----------------------------------------------------------------------
12524        // Load instructions
12525        //----------------------------------------------------------------------
12526        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12527        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12528        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12529        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12530        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12531        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12532        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12533                  // Thumb2 PC-relative load into register
12534        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12535        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12536        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12537        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12538        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12539        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12540        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12541        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12542        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12543        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12544        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12545        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12546        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12547        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12548        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12549        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12550        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12551        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12552        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12553        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12554        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12555        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12556        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12557        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12558        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12559        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12560        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12561        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12562        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12563        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12564        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12565        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12566        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12567
12568        //----------------------------------------------------------------------
12569        // Store instructions
12570        //----------------------------------------------------------------------
12571        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12572        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12573        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12574        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12575        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12576        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12577        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12578        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12579        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12580        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12581        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12582        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12583        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12584        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12585        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12586        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12587        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12588        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12589        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12590        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12591        { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12592        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12593
12594        //----------------------------------------------------------------------
12595        // Other instructions
12596        //----------------------------------------------------------------------
12597        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12598        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12599        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12600        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12601        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12602        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12603        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12604        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12605    };
12606
12607    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12608    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12609    {
12610        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
12611            return &g_thumb_opcodes[i];
12612    }
12613    return NULL;
12614}
12615
12616bool
12617EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12618{
12619    m_arch = arch;
12620    m_arm_isa = 0;
12621    const char *arch_cstr = arch.GetArchitectureName ();
12622    if (arch_cstr)
12623    {
12624        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12625        else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
12626        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12627        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12628        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12629        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12630        else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
12631        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12632        else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
12633        else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
12634    }
12635    return m_arm_isa != 0;
12636}
12637
12638bool
12639EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr)
12640{
12641    m_opcode = insn_opcode;
12642
12643    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12644        m_opcode_mode = eModeThumb;
12645	else
12646	{
12647		AddressClass addr_class = inst_addr.GetAddressClass();
12648
12649    	if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12650        	m_opcode_mode = eModeARM;
12651    	else if (addr_class == eAddressClassCodeAlternateISA)
12652        	m_opcode_mode = eModeThumb;
12653    	else
12654        	return false;
12655	}
12656    return true;
12657}
12658
12659bool
12660EmulateInstructionARM::ReadInstruction ()
12661{
12662    bool success = false;
12663    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12664    if (success)
12665    {
12666        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12667        if (success)
12668        {
12669            Context read_inst_context;
12670            read_inst_context.type = eContextReadOpcode;
12671            read_inst_context.SetNoArgs ();
12672
12673            if (m_opcode_cpsr & MASK_CPSR_T)
12674            {
12675                m_opcode_mode = eModeThumb;
12676                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12677
12678                if (success)
12679                {
12680                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12681                    {
12682                        m_opcode.SetOpcode16 (thumb_opcode);
12683                    }
12684                    else
12685                    {
12686                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12687                    }
12688                }
12689            }
12690            else
12691            {
12692                m_opcode_mode = eModeARM;
12693                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12694            }
12695        }
12696    }
12697    if (!success)
12698    {
12699        m_opcode_mode = eModeInvalid;
12700        m_opcode_pc = LLDB_INVALID_ADDRESS;
12701    }
12702    return success;
12703}
12704
12705uint32_t
12706EmulateInstructionARM::ArchVersion ()
12707{
12708    return m_arm_isa;
12709}
12710
12711bool
12712EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
12713{
12714
12715    const uint32_t cond = CurrentCond (opcode);
12716
12717    if (cond == UINT32_MAX)
12718        return false;
12719
12720    bool result = false;
12721    switch (UnsignedBits(cond, 3, 1))
12722    {
12723    case 0:
12724		if (m_opcode_cpsr == 0)
12725			return true;
12726		result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12727		break;
12728    case 1:
12729 		if (m_opcode_cpsr == 0)
12730			return true;
12731		result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12732		break;
12733    case 2:
12734 		if (m_opcode_cpsr == 0)
12735			return true;
12736		result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12737		break;
12738    case 3:
12739 		if (m_opcode_cpsr == 0)
12740			return true;
12741		result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12742		break;
12743    case 4:
12744 		if (m_opcode_cpsr == 0)
12745			return true;
12746		result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12747		break;
12748    case 5:
12749  		if (m_opcode_cpsr == 0)
12750			return true;
12751       	else
12752		{
12753            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12754            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12755            result = n == v;
12756        }
12757        break;
12758    case 6:
12759  		if (m_opcode_cpsr == 0)
12760			return true;
12761       	else
12762		{
12763            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12764            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12765            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12766        }
12767        break;
12768    case 7:
12769        result = true;
12770        break;
12771    }
12772
12773    if (cond & 1)
12774        result = !result;
12775    return result;
12776}
12777
12778uint32_t
12779EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12780{
12781    switch (m_opcode_mode)
12782    {
12783    default:
12784    case eModeInvalid:
12785        break;
12786
12787    case eModeARM:
12788        return UnsignedBits(opcode, 31, 28);
12789
12790    case eModeThumb:
12791        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12792        // 'cond' field of the encoding.
12793        {
12794            const uint32_t byte_size = m_opcode.GetByteSize();
12795            if (byte_size == 2)
12796            {
12797                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
12798                    return Bits32(opcode, 11, 7);
12799            }
12800            else
12801            {
12802                assert (byte_size == 4);
12803                if (Bits32(opcode, 31, 27) == 0x1e &&
12804                    Bits32(opcode, 15, 14) == 0x02 &&
12805                    Bits32(opcode, 12, 12) == 0x00 &&
12806                    Bits32(opcode, 25, 22) <= 0x0d)
12807                {
12808                    return Bits32(opcode, 25, 22);
12809                }
12810            }
12811
12812            return m_it_session.GetCond();
12813        }
12814    }
12815    return UINT32_MAX;  // Return invalid value
12816}
12817
12818bool
12819EmulateInstructionARM::InITBlock()
12820{
12821    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
12822}
12823
12824bool
12825EmulateInstructionARM::LastInITBlock()
12826{
12827    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
12828}
12829
12830bool
12831EmulateInstructionARM::BadMode (uint32_t mode)
12832{
12833
12834    switch (mode)
12835    {
12836        case 16: return false; // '10000'
12837        case 17: return false; // '10001'
12838        case 18: return false; // '10010'
12839        case 19: return false; // '10011'
12840        case 22: return false; // '10110'
12841        case 23: return false; // '10111'
12842        case 27: return false; // '11011'
12843        case 31: return false; // '11111'
12844        default: return true;
12845    }
12846    return true;
12847}
12848
12849bool
12850EmulateInstructionARM::CurrentModeIsPrivileged ()
12851{
12852    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
12853
12854    if (BadMode (mode))
12855        return false;
12856
12857    if (mode == 16)
12858                  return false;
12859
12860    return true;
12861}
12862
12863void
12864EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
12865{
12866    bool privileged = CurrentModeIsPrivileged();
12867
12868    uint32_t tmp_cpsr = 0;
12869
12870    tmp_cpsr = tmp_cpsr | (Bits32 (m_opcode_cpsr, 23, 20) << 20);
12871
12872    if (BitIsSet (bytemask, 3))
12873    {
12874        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
12875        if (affect_execstate)
12876            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
12877    }
12878
12879    if (BitIsSet (bytemask, 2))
12880    {
12881        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
12882    }
12883
12884    if (BitIsSet (bytemask, 1))
12885    {
12886        if (affect_execstate)
12887            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
12888        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
12889        if (privileged)
12890            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
12891    }
12892
12893    if (BitIsSet (bytemask, 0))
12894    {
12895        if (privileged)
12896            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
12897        if (affect_execstate)
12898            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
12899        if (privileged)
12900            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
12901    }
12902
12903    m_opcode_cpsr = tmp_cpsr;
12904}
12905
12906
12907bool
12908EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
12909{
12910    addr_t target;
12911
12912    // Check the current instruction set.
12913    if (CurrentInstrSet() == eModeARM)
12914        target = addr & 0xfffffffc;
12915    else
12916        target = addr & 0xfffffffe;
12917
12918    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12919        return false;
12920
12921    return true;
12922}
12923
12924// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
12925bool
12926EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
12927{
12928    addr_t target;
12929    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
12930    // we want to record it and issue a WriteRegister callback so the clients
12931    // can track the mode changes accordingly.
12932    bool cpsr_changed = false;
12933
12934    if (BitIsSet(addr, 0))
12935    {
12936        if (CurrentInstrSet() != eModeThumb)
12937        {
12938            SelectInstrSet(eModeThumb);
12939            cpsr_changed = true;
12940        }
12941        target = addr & 0xfffffffe;
12942        context.SetMode (eModeThumb);
12943    }
12944    else if (BitIsClear(addr, 1))
12945    {
12946        if (CurrentInstrSet() != eModeARM)
12947        {
12948            SelectInstrSet(eModeARM);
12949            cpsr_changed = true;
12950        }
12951        target = addr & 0xfffffffc;
12952        context.SetMode (eModeARM);
12953    }
12954    else
12955        return false; // address<1:0> == '10' => UNPREDICTABLE
12956
12957    if (cpsr_changed)
12958    {
12959        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
12960            return false;
12961    }
12962    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12963        return false;
12964
12965    return true;
12966}
12967
12968// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
12969bool
12970EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
12971{
12972    if (ArchVersion() >= ARMv5T)
12973        return BXWritePC(context, addr);
12974    else
12975        return BranchWritePC((const Context)context, addr);
12976}
12977
12978// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
12979bool
12980EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
12981{
12982    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
12983        return BXWritePC(context, addr);
12984    else
12985        return BranchWritePC((const Context)context, addr);
12986}
12987
12988EmulateInstructionARM::Mode
12989EmulateInstructionARM::CurrentInstrSet ()
12990{
12991    return m_opcode_mode;
12992}
12993
12994// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
12995// ReadInstruction() is performed.  This function has a side effect of updating
12996// the m_new_inst_cpsr member variable if necessary.
12997bool
12998EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
12999{
13000    m_new_inst_cpsr = m_opcode_cpsr;
13001    switch (arm_or_thumb)
13002    {
13003    default:
13004        return false;
13005    eModeARM:
13006        // Clear the T bit.
13007        m_new_inst_cpsr &= ~MASK_CPSR_T;
13008        break;
13009    eModeThumb:
13010        // Set the T bit.
13011        m_new_inst_cpsr |= MASK_CPSR_T;
13012        break;
13013    }
13014    return true;
13015}
13016
13017// This function returns TRUE if the processor currently provides support for
13018// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13019// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13020bool
13021EmulateInstructionARM::UnalignedSupport()
13022{
13023    return (ArchVersion() >= ARMv7);
13024}
13025
13026// The main addition and subtraction instructions can produce status information
13027// about both unsigned carry and signed overflow conditions.  This status
13028// information can be used to synthesize multi-word additions and subtractions.
13029EmulateInstructionARM::AddWithCarryResult
13030EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13031{
13032    uint32_t result;
13033    uint8_t carry_out;
13034    uint8_t overflow;
13035
13036    uint64_t unsigned_sum = x + y + carry_in;
13037    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13038
13039    result = UnsignedBits(unsigned_sum, 31, 0);
13040//    carry_out = (result == unsigned_sum ? 0 : 1);
13041    overflow = ((int32_t)result == signed_sum ? 0 : 1);
13042
13043    if (carry_in)
13044        carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13045    else
13046        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13047
13048    AddWithCarryResult res = { result, carry_out, overflow };
13049    return res;
13050}
13051
13052uint32_t
13053EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13054{
13055    uint32_t reg_kind, reg_num;
13056    switch (num)
13057    {
13058    case SP_REG:
13059        reg_kind = eRegisterKindGeneric;
13060        reg_num  = LLDB_REGNUM_GENERIC_SP;
13061        break;
13062    case LR_REG:
13063        reg_kind = eRegisterKindGeneric;
13064        reg_num  = LLDB_REGNUM_GENERIC_RA;
13065        break;
13066    case PC_REG:
13067        reg_kind = eRegisterKindGeneric;
13068        reg_num  = LLDB_REGNUM_GENERIC_PC;
13069        break;
13070    default:
13071        if (num < SP_REG)
13072        {
13073            reg_kind = eRegisterKindDWARF;
13074            reg_num  = dwarf_r0 + num;
13075        }
13076        else
13077        {
13078            assert(0 && "Invalid register number");
13079            *success = false;
13080            return UINT32_MAX;
13081        }
13082        break;
13083    }
13084
13085    // Read our register.
13086    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13087
13088    // When executing an ARM instruction , PC reads as the address of the current
13089    // instruction plus 8.
13090    // When executing a Thumb instruction , PC reads as the address of the current
13091    // instruction plus 4.
13092    if (num == 15)
13093    {
13094        if (CurrentInstrSet() == eModeARM)
13095            val += 8;
13096        else
13097            val += 4;
13098    }
13099
13100    return val;
13101}
13102
13103// Write the result to the ARM core register Rd, and optionally update the
13104// condition flags based on the result.
13105//
13106// This helper method tries to encapsulate the following pseudocode from the
13107// ARM Architecture Reference Manual:
13108//
13109// if d == 15 then         // Can only occur for encoding A1
13110//     ALUWritePC(result); // setflags is always FALSE here
13111// else
13112//     R[d] = result;
13113//     if setflags then
13114//         APSR.N = result<31>;
13115//         APSR.Z = IsZeroBit(result);
13116//         APSR.C = carry;
13117//         // APSR.V unchanged
13118//
13119// In the above case, the API client does not pass in the overflow arg, which
13120// defaults to ~0u.
13121bool
13122EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13123                                                  const uint32_t result,
13124                                                  const uint32_t Rd,
13125                                                  bool setflags,
13126                                                  const uint32_t carry,
13127                                                  const uint32_t overflow)
13128{
13129    if (Rd == 15)
13130    {
13131        if (!ALUWritePC (context, result))
13132            return false;
13133    }
13134    else
13135    {
13136        uint32_t reg_kind, reg_num;
13137        switch (Rd)
13138        {
13139        case SP_REG:
13140            reg_kind = eRegisterKindGeneric;
13141            reg_num  = LLDB_REGNUM_GENERIC_SP;
13142            break;
13143        case LR_REG:
13144            reg_kind = eRegisterKindGeneric;
13145            reg_num  = LLDB_REGNUM_GENERIC_RA;
13146            break;
13147        default:
13148            reg_kind = eRegisterKindDWARF;
13149            reg_num  = dwarf_r0 + Rd;
13150        }
13151        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13152            return false;
13153        if (setflags)
13154            return WriteFlags (context, result, carry, overflow);
13155    }
13156    return true;
13157}
13158
13159// This helper method tries to encapsulate the following pseudocode from the
13160// ARM Architecture Reference Manual:
13161//
13162// APSR.N = result<31>;
13163// APSR.Z = IsZeroBit(result);
13164// APSR.C = carry;
13165// APSR.V = overflow
13166//
13167// Default arguments can be specified for carry and overflow parameters, which means
13168// not to update the respective flags.
13169bool
13170EmulateInstructionARM::WriteFlags (Context &context,
13171                                   const uint32_t result,
13172                                   const uint32_t carry,
13173                                   const uint32_t overflow)
13174{
13175    m_new_inst_cpsr = m_opcode_cpsr;
13176    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13177    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13178    if (carry != ~0u)
13179        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13180    if (overflow != ~0u)
13181        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13182    if (m_new_inst_cpsr != m_opcode_cpsr)
13183    {
13184        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13185            return false;
13186    }
13187    return true;
13188}
13189
13190bool
13191EmulateInstructionARM::EvaluateInstruction ()
13192{
13193    // Advance the ITSTATE bits to their values for the next instruction.
13194    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13195        m_it_session.ITAdvance();
13196
13197
13198    ARMOpcode *opcode_data;
13199
13200    if (m_opcode_mode == eModeThumb)
13201        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32());
13202    else if (m_opcode_mode == eModeARM)
13203        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32());
13204    else
13205        return false;
13206
13207    if (!opcode_data)
13208        return false;
13209    // Verify that we're the right arch for this opcode
13210
13211    switch (m_arm_isa)
13212    {
13213    case ARMv4:
13214        if (opcode_data->variants != ARMvAll)
13215            return false;
13216        break;
13217
13218    case ARMv4T:
13219        if ((opcode_data->variants!= ARMvAll)
13220            && (opcode_data->variants != ARMV4T_ABOVE))
13221            return false;
13222        break;
13223
13224    case ARMv5T:
13225    case ARMv5TE:
13226        if ((opcode_data->variants != ARMvAll)
13227            && (opcode_data->variants != ARMV4T_ABOVE)
13228            && (opcode_data->variants != ARMV5_ABOVE))
13229            return false;
13230        break;
13231
13232    case ARMv5TEJ:
13233        if ((opcode_data->variants != ARMvAll)
13234            && (opcode_data->variants != ARMV4T_ABOVE)
13235            && (opcode_data->variants != ARMV5_ABOVE)
13236            && (opcode_data->variants != ARMV5J_ABOVE))
13237            return false;
13238        break;
13239
13240    case ARMv6:
13241    case ARMv6K:
13242        if ((opcode_data->variants != ARMvAll)
13243            && (opcode_data->variants != ARMV4T_ABOVE)
13244            && (opcode_data->variants != ARMV5_ABOVE)
13245            && (opcode_data->variants != ARMV5J_ABOVE)
13246            && (opcode_data->variants != ARMV6_ABOVE))
13247            return false;
13248        break;
13249
13250    case ARMv6T2:
13251    case ARMv7:
13252    case ARMv8:
13253        if ((opcode_data->variants != ARMvAll)
13254            && (opcode_data->variants != ARMV4T_ABOVE)
13255            && (opcode_data->variants != ARMV5_ABOVE)
13256            && (opcode_data->variants != ARMV5J_ABOVE)
13257            && (opcode_data->variants != ARMV6_ABOVE)
13258            && (opcode_data->variants != ARMV6T2_ABOVE))
13259            return false;
13260        break;
13261
13262    default:
13263//            if (opcode_data->variants != ARMvAll)
13264//                return false;
13265        break;
13266    }
13267
13268    // Just for now, for testing purposes.
13269    if (m_baton == NULL)
13270        fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(),
13271                 opcode_data->name);
13272
13273    bool success;
13274    if (m_baton)
13275    {
13276        uint32_t cpsr_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
13277        if (success)
13278            m_opcode_cpsr = cpsr_value;
13279    }
13280
13281    uint32_t orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13282    if (!success)
13283        return false;
13284
13285    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);  // Call the Emulate... function.
13286    if (!success)
13287        return false;
13288
13289    uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13290    if (!success)
13291        return false;
13292
13293    if (m_advance_pc && (after_pc_value == orig_pc_value))
13294    {
13295        if (opcode_data->size == eSize32)
13296            after_pc_value += 4;
13297        else if (opcode_data->size == eSize16)
13298            after_pc_value += 2;
13299
13300        EmulateInstruction::Context context;
13301        context.type = eContextAdvancePC;
13302        context.SetNoArgs();
13303        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13304            return false;
13305
13306    }
13307
13308    return true;
13309}
13310
13311bool
13312EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13313{
13314    if (!test_data)
13315    {
13316        out_stream->Printf ("TestEmulation: Missing test data.\n");
13317        return false;
13318    }
13319
13320    static ConstString opcode_key ("opcode");
13321    static ConstString before_key ("before_state");
13322    static ConstString after_key ("after_state");
13323
13324    OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13325
13326    uint32_t test_opcode;
13327    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13328    {
13329        out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13330        return false;
13331    }
13332    test_opcode = value_sp->GetUInt64Value ();
13333
13334    // If the instruction emulation does not directly update the PC, advance the PC to the next instruction after
13335    // performing the emulation.
13336    SetAdvancePC (true);
13337
13338    if (arch.GetTriple().getArch() == llvm::Triple::arm)
13339    {
13340        m_opcode_mode = eModeARM;
13341        m_opcode.SetOpcode32 (test_opcode);
13342    }
13343    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13344    {
13345        m_opcode_mode = eModeThumb;
13346        if (test_opcode < 0x10000)
13347            m_opcode.SetOpcode16 (test_opcode);
13348        else
13349            m_opcode.SetOpcode32 (test_opcode);
13350
13351    }
13352    else
13353    {
13354        out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13355        return false;
13356    }
13357
13358    EmulationStateARM before_state;
13359    EmulationStateARM after_state;
13360
13361    value_sp = test_data->GetValueForKey (before_key);
13362    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13363    {
13364        out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13365        return false;
13366    }
13367
13368    OptionValueDictionary *state_dictionary = value_sp->GetAsDictionaryValue ();
13369    if (!before_state.LoadStateFromDictionary (state_dictionary))
13370    {
13371        out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13372        return false;
13373    }
13374
13375    value_sp = test_data->GetValueForKey (after_key);
13376    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13377    {
13378        out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13379        return false;
13380    }
13381
13382    state_dictionary = value_sp->GetAsDictionaryValue ();
13383    if (!after_state.LoadStateFromDictionary (state_dictionary))
13384    {
13385        out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13386        return false;
13387    }
13388
13389    SetBaton ((void *) &before_state);
13390    SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13391                  &EmulationStateARM::WritePseudoMemory,
13392                  &EmulationStateARM::ReadPseudoRegister,
13393                  &EmulationStateARM::WritePseudoRegister);
13394
13395    bool success = EvaluateInstruction ();
13396    if (!success)
13397    {
13398        out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13399        return false;
13400    }
13401
13402    success = before_state.CompareState (after_state);
13403    if (!success)
13404        out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13405
13406    return success;
13407}
13408
13409