EmulateInstructionARM.cpp revision 93767b8fceecd605d3e3dc3803b7d51823f17b2f
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 "lldb/Core/ArchSpec.h"
14#include "lldb/Core/ConstString.h"
15
16#include "Plugins/Process/Utility/ARMDefines.h"
17#include "Plugins/Process/Utility/ARMUtils.h"
18#include "Utility/ARM_DWARF_Registers.h"
19
20#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
21                                     // and CountTrailingZeros_32 function
22
23using namespace lldb;
24using namespace lldb_private;
25
26// Convenient macro definitions.
27#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
28#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
29
30#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
31
32//----------------------------------------------------------------------
33//
34// ITSession implementation
35//
36//----------------------------------------------------------------------
37
38// A8.6.50
39// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
40static unsigned short CountITSize(unsigned ITMask) {
41    // First count the trailing zeros of the IT mask.
42    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
43    if (TZ > 3)
44    {
45        printf("Encoding error: IT Mask '0000'\n");
46        return 0;
47    }
48    return (4 - TZ);
49}
50
51// Init ITState.  Note that at least one bit is always 1 in mask.
52bool ITSession::InitIT(unsigned short bits7_0)
53{
54    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
55    if (ITCounter == 0)
56        return false;
57
58    // A8.6.50 IT
59    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
60    if (FirstCond == 0xF)
61    {
62        printf("Encoding error: IT FirstCond '1111'\n");
63        return false;
64    }
65    if (FirstCond == 0xE && ITCounter != 1)
66    {
67        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
68        return false;
69    }
70
71    ITState = bits7_0;
72    return true;
73}
74
75// Update ITState if necessary.
76void ITSession::ITAdvance()
77{
78    assert(ITCounter);
79    --ITCounter;
80    if (ITCounter == 0)
81        ITState = 0;
82    else
83    {
84        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
85        SetBits32(ITState, 4, 0, NewITState4_0);
86    }
87}
88
89// Return true if we're inside an IT Block.
90bool ITSession::InITBlock()
91{
92    return ITCounter != 0;
93}
94
95// Return true if we're the last instruction inside an IT Block.
96bool ITSession::LastInITBlock()
97{
98    return ITCounter == 1;
99}
100
101// Get condition bits for the current thumb instruction.
102uint32_t ITSession::GetCond()
103{
104    if (InITBlock())
105        return Bits32(ITState, 7, 4);
106    else
107        return COND_AL;
108}
109
110// ARM constants used during decoding
111#define REG_RD          0
112#define LDM_REGLIST     1
113#define SP_REG          13
114#define LR_REG          14
115#define PC_REG          15
116#define PC_REGLIST_BIT  0x8000
117
118#define ARMv4     (1u << 0)
119#define ARMv4T    (1u << 1)
120#define ARMv5T    (1u << 2)
121#define ARMv5TE   (1u << 3)
122#define ARMv5TEJ  (1u << 4)
123#define ARMv6     (1u << 5)
124#define ARMv6K    (1u << 6)
125#define ARMv6T2   (1u << 7)
126#define ARMv7     (1u << 8)
127#define ARMv8     (1u << 9)
128#define ARMvAll   (0xffffffffu)
129
130#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
131#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
132#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
133#define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
134#define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
135#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
136
137#define No_VFP  0
138#define VFPv1   (1u << 1)
139#define VFPv2   (1u << 2)
140#define VFPv3   (1u << 3)
141#define AdvancedSIMD (1u << 4)
142
143#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
144#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
145#define VFPv2v3     (VFPv2 | VFPv3)
146
147//----------------------------------------------------------------------
148//
149// EmulateInstructionARM implementation
150//
151//----------------------------------------------------------------------
152
153void
154EmulateInstructionARM::Initialize ()
155{
156}
157
158void
159EmulateInstructionARM::Terminate ()
160{
161}
162
163// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
164bool
165EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
166{
167    EmulateInstruction::Context context;
168    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
169    context.SetNoArgs ();
170
171    uint32_t random_data = rand ();
172    const uint32_t addr_byte_size = GetAddressByteSize();
173
174    if (!MemAWrite (context, address, random_data, addr_byte_size))
175        return false;
176
177    return true;
178}
179
180// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
181bool
182EmulateInstructionARM::WriteBits32Unknown (int n)
183{
184    EmulateInstruction::Context context;
185    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
186    context.SetNoArgs ();
187
188    bool success;
189    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
190
191    if (!success)
192        return false;
193
194    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
195        return false;
196
197    return true;
198}
199
200// Push Multiple Registers stores multiple registers to the stack, storing to
201// consecutive memory locations ending just below the address in SP, and updates
202// SP to point to the start of the stored data.
203bool
204EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
205{
206#if 0
207    // ARM pseudo code...
208    if (ConditionPassed())
209    {
210        EncodingSpecificOperations();
211        NullCheckIfThumbEE(13);
212        address = SP - 4*BitCount(registers);
213
214        for (i = 0 to 14)
215        {
216            if (registers<i> == '1')
217            {
218                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
219                    MemA[address,4] = bits(32) UNKNOWN;
220                else
221                    MemA[address,4] = R[i];
222                address = address + 4;
223            }
224        }
225
226        if (registers<15> == '1') // Only possible for encoding A1 or A2
227            MemA[address,4] = PCStoreValue();
228
229        SP = SP - 4*BitCount(registers);
230    }
231#endif
232
233    bool success = false;
234    if (ConditionPassed(opcode))
235    {
236        const uint32_t addr_byte_size = GetAddressByteSize();
237        const addr_t sp = ReadCoreReg (SP_REG, &success);
238        if (!success)
239            return false;
240        uint32_t registers = 0;
241        uint32_t Rt; // the source register
242        switch (encoding) {
243        case eEncodingT1:
244            registers = Bits32(opcode, 7, 0);
245            // The M bit represents LR.
246            if (Bit32(opcode, 8))
247                registers |= (1u << 14);
248            // if BitCount(registers) < 1 then UNPREDICTABLE;
249            if (BitCount(registers) < 1)
250                return false;
251            break;
252        case eEncodingT2:
253            // Ignore bits 15 & 13.
254            registers = Bits32(opcode, 15, 0) & ~0xa000;
255            // if BitCount(registers) < 2 then UNPREDICTABLE;
256            if (BitCount(registers) < 2)
257                return false;
258            break;
259        case eEncodingT3:
260            Rt = Bits32(opcode, 15, 12);
261            // if BadReg(t) then UNPREDICTABLE;
262            if (BadReg(Rt))
263                return false;
264            registers = (1u << Rt);
265            break;
266        case eEncodingA1:
267            registers = Bits32(opcode, 15, 0);
268            // Instead of return false, let's handle the following case as well,
269            // which amounts to pushing one reg onto the full descending stacks.
270            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
271            break;
272        case eEncodingA2:
273            Rt = Bits32(opcode, 15, 12);
274            // if t == 13 then UNPREDICTABLE;
275            if (Rt == dwarf_sp)
276                return false;
277            registers = (1u << Rt);
278            break;
279        default:
280            return false;
281        }
282        addr_t sp_offset = addr_byte_size * BitCount (registers);
283        addr_t addr = sp - sp_offset;
284        uint32_t i;
285
286        EmulateInstruction::Context context;
287        context.type = EmulateInstruction::eContextPushRegisterOnStack;
288        Register dwarf_reg;
289        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
290        Register sp_reg;
291        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
292        for (i=0; i<15; ++i)
293        {
294            if (BitIsSet (registers, i))
295            {
296                dwarf_reg.num = dwarf_r0 + i;
297                context.SetRegisterToRegisterPlusOffset (dwarf_reg, sp_reg, addr - sp);
298                uint32_t reg_value = ReadCoreReg(i, &success);
299                if (!success)
300                    return false;
301                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
302                    return false;
303                addr += addr_byte_size;
304            }
305        }
306
307        if (BitIsSet (registers, 15))
308        {
309            dwarf_reg.num = dwarf_pc;
310            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
311            const uint32_t pc = ReadCoreReg(PC_REG, &success);
312            if (!success)
313                return false;
314            if (!MemAWrite (context, addr, pc, addr_byte_size))
315                return false;
316        }
317
318        context.type = EmulateInstruction::eContextAdjustStackPointer;
319        context.SetImmediateSigned (-sp_offset);
320
321        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
322            return false;
323    }
324    return true;
325}
326
327// Pop Multiple Registers loads multiple registers from the stack, loading from
328// consecutive memory locations staring at the address in SP, and updates
329// SP to point just above the loaded data.
330bool
331EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
332{
333#if 0
334    // ARM pseudo code...
335    if (ConditionPassed())
336    {
337        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
338        address = SP;
339        for i = 0 to 14
340            if registers<i> == '1' then
341                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
342        if registers<15> == '1' then
343            if UnalignedAllowed then
344                LoadWritePC(MemU[address,4]);
345            else
346                LoadWritePC(MemA[address,4]);
347        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
348        if registers<13> == '1' then SP = bits(32) UNKNOWN;
349    }
350#endif
351
352    bool success = false;
353
354    if (ConditionPassed(opcode))
355    {
356        const uint32_t addr_byte_size = GetAddressByteSize();
357        const addr_t sp = ReadCoreReg (SP_REG, &success);
358        if (!success)
359            return false;
360        uint32_t registers = 0;
361        uint32_t Rt; // the destination register
362        switch (encoding) {
363        case eEncodingT1:
364            registers = Bits32(opcode, 7, 0);
365            // The P bit represents PC.
366            if (Bit32(opcode, 8))
367                registers |= (1u << 15);
368            // if BitCount(registers) < 1 then UNPREDICTABLE;
369            if (BitCount(registers) < 1)
370                return false;
371            break;
372        case eEncodingT2:
373            // Ignore bit 13.
374            registers = Bits32(opcode, 15, 0) & ~0x2000;
375            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
376            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
377                return false;
378            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
379            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
380                return false;
381            break;
382        case eEncodingT3:
383            Rt = Bits32(opcode, 15, 12);
384            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
385            if (Rt == 13)
386                return false;
387            if (Rt == 15 && InITBlock() && !LastInITBlock())
388                return false;
389            registers = (1u << Rt);
390            break;
391        case eEncodingA1:
392            registers = Bits32(opcode, 15, 0);
393            // Instead of return false, let's handle the following case as well,
394            // which amounts to popping one reg from the full descending stacks.
395            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
396
397            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
398            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
399                return false;
400            break;
401        case eEncodingA2:
402            Rt = Bits32(opcode, 15, 12);
403            // if t == 13 then UNPREDICTABLE;
404            if (Rt == dwarf_sp)
405                return false;
406            registers = (1u << Rt);
407            break;
408        default:
409            return false;
410        }
411        addr_t sp_offset = addr_byte_size * BitCount (registers);
412        addr_t addr = sp;
413        uint32_t i, data;
414
415        EmulateInstruction::Context context;
416        context.type = EmulateInstruction::eContextPopRegisterOffStack;
417        Register dwarf_reg;
418        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
419        Register sp_reg;
420        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
421        for (i=0; i<15; ++i)
422        {
423            if (BitIsSet (registers, i))
424            {
425                dwarf_reg.num = dwarf_r0 + i;
426                context.SetRegisterPlusOffset (sp_reg, addr - sp);
427                data = MemARead(context, addr, 4, 0, &success);
428                if (!success)
429                    return false;
430                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
431                    return false;
432                addr += addr_byte_size;
433            }
434        }
435
436        if (BitIsSet (registers, 15))
437        {
438            dwarf_reg.num = dwarf_pc;
439            context.SetRegisterPlusOffset (sp_reg, addr - sp);
440            data = MemARead(context, addr, 4, 0, &success);
441            if (!success)
442                return false;
443            // In ARMv5T and above, this is an interworking branch.
444            if (!LoadWritePC(context, data))
445                return false;
446            addr += addr_byte_size;
447        }
448
449        context.type = EmulateInstruction::eContextAdjustStackPointer;
450        context.SetImmediateSigned (sp_offset);
451
452        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
453            return false;
454    }
455    return true;
456}
457
458// Set r7 or ip to point to saved value residing within the stack.
459// ADD (SP plus immediate)
460bool
461EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
462{
463#if 0
464    // ARM pseudo code...
465    if (ConditionPassed())
466    {
467        EncodingSpecificOperations();
468        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
469        if d == 15 then
470           ALUWritePC(result); // setflags is always FALSE here
471        else
472            R[d] = result;
473            if setflags then
474                APSR.N = result<31>;
475                APSR.Z = IsZeroBit(result);
476                APSR.C = carry;
477                APSR.V = overflow;
478    }
479#endif
480
481    bool success = false;
482
483    if (ConditionPassed(opcode))
484    {
485        const addr_t sp = ReadCoreReg (SP_REG, &success);
486        if (!success)
487            return false;
488        uint32_t Rd; // the destination register
489        uint32_t imm32;
490        switch (encoding) {
491        case eEncodingT1:
492            Rd = 7;
493            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
494            break;
495        case eEncodingA1:
496            Rd = Bits32(opcode, 15, 12);
497            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
498            break;
499        default:
500            return false;
501        }
502        addr_t sp_offset = imm32;
503        addr_t addr = sp + sp_offset; // a pointer to the stack area
504
505        EmulateInstruction::Context context;
506        context.type = EmulateInstruction::eContextRegisterPlusOffset;
507        Register sp_reg;
508        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
509        context.SetRegisterPlusOffset (sp_reg, sp_offset);
510
511        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
512            return false;
513    }
514    return true;
515}
516
517// Set r7 or ip to the current stack pointer.
518// MOV (register)
519bool
520EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
521{
522#if 0
523    // ARM pseudo code...
524    if (ConditionPassed())
525    {
526        EncodingSpecificOperations();
527        result = R[m];
528        if d == 15 then
529            ALUWritePC(result); // setflags is always FALSE here
530        else
531            R[d] = result;
532            if setflags then
533                APSR.N = result<31>;
534                APSR.Z = IsZeroBit(result);
535                // APSR.C unchanged
536                // APSR.V unchanged
537    }
538#endif
539
540    bool success = false;
541
542    if (ConditionPassed(opcode))
543    {
544        const addr_t sp = ReadCoreReg (SP_REG, &success);
545        if (!success)
546            return false;
547        uint32_t Rd; // the destination register
548        switch (encoding) {
549        case eEncodingT1:
550            Rd = 7;
551            break;
552        case eEncodingA1:
553            Rd = 12;
554            break;
555        default:
556            return false;
557        }
558
559        EmulateInstruction::Context context;
560        context.type = EmulateInstruction::eContextRegisterPlusOffset;
561        Register sp_reg;
562        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
563        context.SetRegisterPlusOffset (sp_reg, 0);
564
565        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
566            return false;
567    }
568    return true;
569}
570
571// Move from high register (r8-r15) to low register (r0-r7).
572// MOV (register)
573bool
574EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
575{
576    return EmulateMOVRdRm (opcode, encoding);
577}
578
579// Move from register to register.
580// MOV (register)
581bool
582EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
583{
584#if 0
585    // ARM pseudo code...
586    if (ConditionPassed())
587    {
588        EncodingSpecificOperations();
589        result = R[m];
590        if d == 15 then
591            ALUWritePC(result); // setflags is always FALSE here
592        else
593            R[d] = result;
594            if setflags then
595                APSR.N = result<31>;
596                APSR.Z = IsZeroBit(result);
597                // APSR.C unchanged
598                // APSR.V unchanged
599    }
600#endif
601
602    bool success = false;
603
604    if (ConditionPassed(opcode))
605    {
606        uint32_t Rm; // the source register
607        uint32_t Rd; // the destination register
608        bool setflags;
609        switch (encoding) {
610        case eEncodingT1:
611            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
612            Rm = Bits32(opcode, 6, 3);
613            setflags = false;
614            if (Rd == 15 && InITBlock() && !LastInITBlock())
615                return false;
616            break;
617        case eEncodingT2:
618            Rd = Bits32(opcode, 2, 0);
619            Rm = Bits32(opcode, 5, 3);
620            setflags = true;
621            if (InITBlock())
622                return false;
623            break;
624        case eEncodingT3:
625            Rd = Bits32(opcode, 11, 8);
626            Rm = Bits32(opcode, 3, 0);
627            setflags = BitIsSet(opcode, 20);
628            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
629            if (setflags && (BadReg(Rd) || BadReg(Rm)))
630                return false;
631            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
632            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
633                return false;
634            break;
635        case eEncodingA1:
636            Rd = Bits32(opcode, 15, 12);
637            Rm = Bits32(opcode, 3, 0);
638            setflags = BitIsSet(opcode, 20);
639            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
640            // TODO: Emulate SUBS PC, LR and related instructions.
641            if (Rd == 15 && setflags)
642                return false;
643            break;
644        default:
645            return false;
646        }
647        uint32_t result = ReadCoreReg(Rm, &success);
648        if (!success)
649            return false;
650
651        // The context specifies that Rm is to be moved into Rd.
652        EmulateInstruction::Context context;
653        context.type = EmulateInstruction::eContextRegisterLoad;
654        Register dwarf_reg;
655        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
656        context.SetRegister (dwarf_reg);
657
658        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
659            return false;
660    }
661    return true;
662}
663
664// Move (immediate) writes an immediate value to the destination register.  It
665// can optionally update the condition flags based on the value.
666// MOV (immediate)
667bool
668EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
669{
670#if 0
671    // ARM pseudo code...
672    if (ConditionPassed())
673    {
674        EncodingSpecificOperations();
675        result = imm32;
676        if d == 15 then         // Can only occur for ARM encoding
677            ALUWritePC(result); // setflags is always FALSE here
678        else
679            R[d] = result;
680            if setflags then
681                APSR.N = result<31>;
682                APSR.Z = IsZeroBit(result);
683                APSR.C = carry;
684                // APSR.V unchanged
685    }
686#endif
687
688    if (ConditionPassed(opcode))
689    {
690        uint32_t Rd; // the destination register
691        uint32_t imm32; // the immediate value to be written to Rd
692        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
693        bool setflags;
694        switch (encoding) {
695            case eEncodingT1:
696                Rd = Bits32(opcode, 10, 8);
697                setflags = !InITBlock();
698                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
699                carry = APSR_C;
700
701                break;
702
703            case eEncodingT2:
704                Rd = Bits32(opcode, 11, 8);
705                setflags = BitIsSet(opcode, 20);
706                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
707                if (BadReg(Rd))
708                  return false;
709
710                break;
711
712            case eEncodingT3:
713            {
714                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
715                Rd = Bits32 (opcode, 11, 8);
716                setflags = false;
717                uint32_t imm4 = Bits32 (opcode, 19, 16);
718                uint32_t imm3 = Bits32 (opcode, 14, 12);
719                uint32_t i = Bit32 (opcode, 26);
720                uint32_t imm8 = Bits32 (opcode, 7, 0);
721                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
722
723                // if BadReg(d) then UNPREDICTABLE;
724                if (BadReg (Rd))
725                    return false;
726            }
727                break;
728
729            case eEncodingA1:
730                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
731                // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
732                Rd = Bits32 (opcode, 15, 12);
733                setflags = BitIsSet (opcode, 20);
734                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
735
736                break;
737
738            case eEncodingA2:
739            {
740                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
741                Rd = Bits32 (opcode, 15, 12);
742                setflags = false;
743                uint32_t imm4 = Bits32 (opcode, 19, 16);
744                uint32_t imm12 = Bits32 (opcode, 11, 0);
745                imm32 = (imm4 << 12) | imm12;
746
747                // if d == 15 then UNPREDICTABLE;
748                if (Rd == 15)
749                    return false;
750            }
751                break;
752
753            default:
754                return false;
755        }
756        uint32_t result = imm32;
757
758        // The context specifies that an immediate is to be moved into Rd.
759        EmulateInstruction::Context context;
760        context.type = EmulateInstruction::eContextImmediate;
761        context.SetNoArgs ();
762
763        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
764            return false;
765    }
766    return true;
767}
768
769// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
770// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
771// unsigned values.
772//
773// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
774// limited to only a few forms of the instruction.
775bool
776EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
777{
778#if 0
779    if ConditionPassed() then
780        EncodingSpecificOperations();
781        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
782        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
783        result = operand1 * operand2;
784        R[d] = result<31:0>;
785        if setflags then
786            APSR.N = result<31>;
787            APSR.Z = IsZeroBit(result);
788            if ArchVersion() == 4 then
789                APSR.C = bit UNKNOWN;
790            // else APSR.C unchanged
791            // APSR.V always unchanged
792#endif
793
794    if (ConditionPassed(opcode))
795    {
796        uint32_t d;
797        uint32_t n;
798        uint32_t m;
799        bool setflags;
800
801        // EncodingSpecificOperations();
802        switch (encoding)
803        {
804            case eEncodingT1:
805                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
806                d = Bits32 (opcode, 2, 0);
807                n = Bits32 (opcode, 5, 3);
808                m = Bits32 (opcode, 2, 0);
809                setflags = !InITBlock();
810
811                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
812                if ((ArchVersion() < ARMv6) && (d == n))
813                    return false;
814
815                break;
816
817            case eEncodingT2:
818                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
819                d = Bits32 (opcode, 11, 8);
820                n = Bits32 (opcode, 19, 16);
821                m = Bits32 (opcode, 3, 0);
822                setflags = false;
823
824                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
825                if (BadReg (d) || BadReg (n) || BadReg (m))
826                    return false;
827
828                break;
829
830            case eEncodingA1:
831                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
832                d = Bits32 (opcode, 19, 16);
833                n = Bits32 (opcode, 3, 0);
834                m = Bits32 (opcode, 11, 8);
835                setflags = BitIsSet (opcode, 20);
836
837                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
838                if ((d == 15) ||  (n == 15) || (m == 15))
839                    return false;
840
841                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
842                if ((ArchVersion() < ARMv6) && (d == n))
843                    return false;
844
845                break;
846
847            default:
848                return false;
849        }
850
851        bool success = false;
852
853        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
854        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
855        if (!success)
856            return false;
857
858        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
859        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
860        if (!success)
861            return false;
862
863        // result = operand1 * operand2;
864        uint64_t result = operand1 * operand2;
865
866        // R[d] = result<31:0>;
867        Register op1_reg;
868        Register op2_reg;
869        op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
870        op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
871
872        EmulateInstruction::Context context;
873        context.type = eContextMultiplication;
874        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
875
876        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
877            return false;
878
879        // if setflags then
880        if (setflags)
881        {
882            // APSR.N = result<31>;
883            // APSR.Z = IsZeroBit(result);
884            m_new_inst_cpsr = m_opcode_cpsr;
885            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
886            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
887            if (m_new_inst_cpsr != m_opcode_cpsr)
888            {
889                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
890                    return false;
891            }
892
893            // if ArchVersion() == 4 then
894                // APSR.C = bit UNKNOWN;
895        }
896    }
897    return true;
898}
899
900// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
901// It can optionally update the condition flags based on the value.
902bool
903EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
904{
905#if 0
906    // ARM pseudo code...
907    if (ConditionPassed())
908    {
909        EncodingSpecificOperations();
910        result = NOT(imm32);
911        if d == 15 then         // Can only occur for ARM encoding
912            ALUWritePC(result); // setflags is always FALSE here
913        else
914            R[d] = result;
915            if setflags then
916                APSR.N = result<31>;
917                APSR.Z = IsZeroBit(result);
918                APSR.C = carry;
919                // APSR.V unchanged
920    }
921#endif
922
923    if (ConditionPassed(opcode))
924    {
925        uint32_t Rd; // the destination register
926        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
927        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
928        bool setflags;
929        switch (encoding) {
930        case eEncodingT1:
931            Rd = Bits32(opcode, 11, 8);
932            setflags = BitIsSet(opcode, 20);
933            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
934            break;
935        case eEncodingA1:
936            Rd = Bits32(opcode, 15, 12);
937            setflags = BitIsSet(opcode, 20);
938            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
939            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
940            // TODO: Emulate SUBS PC, LR and related instructions.
941            if (Rd == 15 && setflags)
942                return false;
943            break;
944        default:
945            return false;
946        }
947        uint32_t result = ~imm32;
948
949        // The context specifies that an immediate is to be moved into Rd.
950        EmulateInstruction::Context context;
951        context.type = EmulateInstruction::eContextImmediate;
952        context.SetNoArgs ();
953
954        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
955            return false;
956    }
957    return true;
958}
959
960// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
961// It can optionally update the condition flags based on the result.
962bool
963EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
964{
965#if 0
966    // ARM pseudo code...
967    if (ConditionPassed())
968    {
969        EncodingSpecificOperations();
970        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
971        result = NOT(shifted);
972        if d == 15 then         // Can only occur for ARM encoding
973            ALUWritePC(result); // setflags is always FALSE here
974        else
975            R[d] = result;
976            if setflags then
977                APSR.N = result<31>;
978                APSR.Z = IsZeroBit(result);
979                APSR.C = carry;
980                // APSR.V unchanged
981    }
982#endif
983
984    if (ConditionPassed(opcode))
985    {
986        uint32_t Rm; // the source register
987        uint32_t Rd; // the destination register
988        ARM_ShifterType shift_t;
989        uint32_t shift_n; // the shift applied to the value read from Rm
990        bool setflags;
991        uint32_t carry; // the carry bit after the shift operation
992        switch (encoding) {
993        case eEncodingT1:
994            Rd = Bits32(opcode, 2, 0);
995            Rm = Bits32(opcode, 5, 3);
996            setflags = !InITBlock();
997            shift_t = SRType_LSL;
998            shift_n = 0;
999            if (InITBlock())
1000                return false;
1001            break;
1002        case eEncodingT2:
1003            Rd = Bits32(opcode, 11, 8);
1004            Rm = Bits32(opcode, 3, 0);
1005            setflags = BitIsSet(opcode, 20);
1006            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1007            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1008            if (BadReg(Rd) || BadReg(Rm))
1009                return false;
1010            break;
1011        case eEncodingA1:
1012            Rd = Bits32(opcode, 15, 12);
1013            Rm = Bits32(opcode, 3, 0);
1014            setflags = BitIsSet(opcode, 20);
1015            shift_n = DecodeImmShiftARM(opcode, shift_t);
1016            break;
1017        default:
1018            return false;
1019        }
1020        bool success = false;
1021        uint32_t value = ReadCoreReg(Rm, &success);
1022        if (!success)
1023            return false;
1024
1025        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry);
1026        uint32_t result = ~shifted;
1027
1028        // The context specifies that an immediate is to be moved into Rd.
1029        EmulateInstruction::Context context;
1030        context.type = EmulateInstruction::eContextImmediate;
1031        context.SetNoArgs ();
1032
1033        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1034            return false;
1035    }
1036    return true;
1037}
1038
1039// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1040// LDR (literal)
1041bool
1042EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1043{
1044#if 0
1045    // ARM pseudo code...
1046    if (ConditionPassed())
1047    {
1048        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1049        base = Align(PC,4);
1050        address = if add then (base + imm32) else (base - imm32);
1051        data = MemU[address,4];
1052        if t == 15 then
1053            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1054        elsif UnalignedSupport() || address<1:0> = '00' then
1055            R[t] = data;
1056        else // Can only apply before ARMv7
1057            if CurrentInstrSet() == InstrSet_ARM then
1058                R[t] = ROR(data, 8*UInt(address<1:0>));
1059            else
1060                R[t] = bits(32) UNKNOWN;
1061    }
1062#endif
1063
1064    if (ConditionPassed(opcode))
1065    {
1066        bool success = false;
1067        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1068        if (!success)
1069            return false;
1070
1071        // PC relative immediate load context
1072        EmulateInstruction::Context context;
1073        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1074        Register pc_reg;
1075        pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1076        context.SetRegisterPlusOffset (pc_reg, 0);
1077
1078        uint32_t Rt;    // the destination register
1079        uint32_t imm32; // immediate offset from the PC
1080        bool add;       // +imm32 or -imm32?
1081        addr_t base;    // the base address
1082        addr_t address; // the PC relative address
1083        uint32_t data;  // the literal data value from the PC relative load
1084        switch (encoding) {
1085        case eEncodingT1:
1086            Rt = Bits32(opcode, 10, 8);
1087            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1088            add = true;
1089            break;
1090        case eEncodingT2:
1091            Rt = Bits32(opcode, 15, 12);
1092            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1093            add = BitIsSet(opcode, 23);
1094            if (Rt == 15 && InITBlock() && !LastInITBlock())
1095                return false;
1096            break;
1097        default:
1098            return false;
1099        }
1100
1101        base = Align(pc, 4);
1102        if (add)
1103            address = base + imm32;
1104        else
1105            address = base - imm32;
1106
1107        context.SetRegisterPlusOffset(pc_reg, address - base);
1108        data = MemURead(context, address, 4, 0, &success);
1109        if (!success)
1110            return false;
1111
1112        if (Rt == 15)
1113        {
1114            if (Bits32(address, 1, 0) == 0)
1115            {
1116                // In ARMv5T and above, this is an interworking branch.
1117                if (!LoadWritePC(context, data))
1118                    return false;
1119            }
1120            else
1121                return false;
1122        }
1123        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1124        {
1125            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1126                return false;
1127        }
1128        else // We don't handle ARM for now.
1129            return false;
1130
1131    }
1132    return true;
1133}
1134
1135// An add operation to adjust the SP.
1136// ADD (SP plus immediate)
1137bool
1138EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1139{
1140#if 0
1141    // ARM pseudo code...
1142    if (ConditionPassed())
1143    {
1144        EncodingSpecificOperations();
1145        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1146        if d == 15 then // Can only occur for ARM encoding
1147            ALUWritePC(result); // setflags is always FALSE here
1148        else
1149            R[d] = result;
1150            if setflags then
1151                APSR.N = result<31>;
1152                APSR.Z = IsZeroBit(result);
1153                APSR.C = carry;
1154                APSR.V = overflow;
1155    }
1156#endif
1157
1158    bool success = false;
1159
1160    if (ConditionPassed(opcode))
1161    {
1162        const addr_t sp = ReadCoreReg (SP_REG, &success);
1163        if (!success)
1164            return false;
1165        uint32_t imm32; // the immediate operand
1166        uint32_t d;
1167        bool setflags;
1168        switch (encoding)
1169        {
1170            case eEncodingT1:
1171                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1172                d = Bits32 (opcode, 10, 8);
1173                setflags = false;
1174                imm32 = (Bits32 (opcode, 7, 0) << 2);
1175
1176                break;
1177
1178            case eEncodingT2:
1179                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1180                d = 13;
1181                setflags = false;
1182                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1183
1184                break;
1185
1186            default:
1187                return false;
1188        }
1189        addr_t sp_offset = imm32;
1190        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1191
1192        EmulateInstruction::Context context;
1193        context.type = EmulateInstruction::eContextAdjustStackPointer;
1194        context.SetImmediateSigned (sp_offset);
1195
1196        if (d == 15)
1197        {
1198            if (!ALUWritePC (context, addr))
1199                return false;
1200        }
1201        else
1202        {
1203            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1204                return false;
1205        }
1206    }
1207    return true;
1208}
1209
1210// An add operation to adjust the SP.
1211// ADD (SP plus register)
1212bool
1213EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1214{
1215#if 0
1216    // ARM pseudo code...
1217    if (ConditionPassed())
1218    {
1219        EncodingSpecificOperations();
1220        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1221        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1222        if d == 15 then
1223            ALUWritePC(result); // setflags is always FALSE here
1224        else
1225            R[d] = result;
1226            if setflags then
1227                APSR.N = result<31>;
1228                APSR.Z = IsZeroBit(result);
1229                APSR.C = carry;
1230                APSR.V = overflow;
1231    }
1232#endif
1233
1234    bool success = false;
1235
1236    if (ConditionPassed(opcode))
1237    {
1238        const addr_t sp = ReadCoreReg (SP_REG, &success);
1239        if (!success)
1240            return false;
1241        uint32_t Rm; // the second operand
1242        switch (encoding) {
1243        case eEncodingT2:
1244            Rm = Bits32(opcode, 6, 3);
1245            break;
1246        default:
1247            return false;
1248        }
1249        int32_t reg_value = ReadCoreReg(Rm, &success);
1250        if (!success)
1251            return false;
1252
1253        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1254
1255        EmulateInstruction::Context context;
1256        context.type = EmulateInstruction::eContextAdjustStackPointer;
1257        context.SetImmediateSigned (reg_value);
1258
1259        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1260            return false;
1261    }
1262    return true;
1263}
1264
1265// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1266// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1267// from Thumb to ARM.
1268// BLX (immediate)
1269bool
1270EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1271{
1272#if 0
1273    // ARM pseudo code...
1274    if (ConditionPassed())
1275    {
1276        EncodingSpecificOperations();
1277        if CurrentInstrSet() == InstrSet_ARM then
1278            LR = PC - 4;
1279        else
1280            LR = PC<31:1> : '1';
1281        if targetInstrSet == InstrSet_ARM then
1282            targetAddress = Align(PC,4) + imm32;
1283        else
1284            targetAddress = PC + imm32;
1285        SelectInstrSet(targetInstrSet);
1286        BranchWritePC(targetAddress);
1287    }
1288#endif
1289
1290    bool success = true;
1291
1292    if (ConditionPassed(opcode))
1293    {
1294        EmulateInstruction::Context context;
1295        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1296        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1297        if (!success)
1298            return false;
1299        addr_t lr; // next instruction address
1300        addr_t target; // target address
1301        int32_t imm32; // PC-relative offset
1302        switch (encoding) {
1303        case eEncodingT1:
1304            {
1305            lr = pc | 1u; // return address
1306            uint32_t S = Bit32(opcode, 26);
1307            uint32_t imm10 = Bits32(opcode, 25, 16);
1308            uint32_t J1 = Bit32(opcode, 13);
1309            uint32_t J2 = Bit32(opcode, 11);
1310            uint32_t imm11 = Bits32(opcode, 10, 0);
1311            uint32_t I1 = !(J1 ^ S);
1312            uint32_t I2 = !(J2 ^ S);
1313            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1314            imm32 = llvm::SignExtend32<25>(imm25);
1315            target = pc + imm32;
1316            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1317            if (InITBlock() && !LastInITBlock())
1318                return false;
1319            break;
1320            }
1321        case eEncodingT2:
1322            {
1323            lr = pc | 1u; // return address
1324            uint32_t S = Bit32(opcode, 26);
1325            uint32_t imm10H = Bits32(opcode, 25, 16);
1326            uint32_t J1 = Bit32(opcode, 13);
1327            uint32_t J2 = Bit32(opcode, 11);
1328            uint32_t imm10L = Bits32(opcode, 10, 1);
1329            uint32_t I1 = !(J1 ^ S);
1330            uint32_t I2 = !(J2 ^ S);
1331            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1332            imm32 = llvm::SignExtend32<25>(imm25);
1333            target = Align(pc, 4) + imm32;
1334            context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1335            if (InITBlock() && !LastInITBlock())
1336                return false;
1337            break;
1338            }
1339        case eEncodingA1:
1340            lr = pc - 4; // return address
1341            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1342            target = Align(pc, 4) + imm32;
1343            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1344            break;
1345        case eEncodingA2:
1346            lr = pc - 4; // return address
1347            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1348            target = pc + imm32;
1349            context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
1350            break;
1351        default:
1352            return false;
1353        }
1354        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1355            return false;
1356        if (!BranchWritePC(context, target))
1357            return false;
1358    }
1359    return true;
1360}
1361
1362// Branch with Link and Exchange (register) calls a subroutine at an address and
1363// instruction set specified by a register.
1364// BLX (register)
1365bool
1366EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1367{
1368#if 0
1369    // ARM pseudo code...
1370    if (ConditionPassed())
1371    {
1372        EncodingSpecificOperations();
1373        target = R[m];
1374        if CurrentInstrSet() == InstrSet_ARM then
1375            next_instr_addr = PC - 4;
1376            LR = next_instr_addr;
1377        else
1378            next_instr_addr = PC - 2;
1379            LR = next_instr_addr<31:1> : '1';
1380        BXWritePC(target);
1381    }
1382#endif
1383
1384    bool success = false;
1385
1386    if (ConditionPassed(opcode))
1387    {
1388        EmulateInstruction::Context context;
1389        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1390        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1391        addr_t lr; // next instruction address
1392        if (!success)
1393            return false;
1394        uint32_t Rm; // the register with the target address
1395        switch (encoding) {
1396        case eEncodingT1:
1397            lr = (pc - 2) | 1u; // return address
1398            Rm = Bits32(opcode, 6, 3);
1399            // if m == 15 then UNPREDICTABLE;
1400            if (Rm == 15)
1401                return false;
1402            if (InITBlock() && !LastInITBlock())
1403                return false;
1404            break;
1405        case eEncodingA1:
1406            lr = pc - 4; // return address
1407            Rm = Bits32(opcode, 3, 0);
1408            // if m == 15 then UNPREDICTABLE;
1409            if (Rm == 15)
1410                return false;
1411            break;
1412        default:
1413            return false;
1414        }
1415        addr_t target = ReadCoreReg (Rm, &success);
1416        if (!success)
1417            return false;
1418        Register dwarf_reg;
1419        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1420        context.SetRegister (dwarf_reg);
1421        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1422            return false;
1423        if (!BXWritePC(context, target))
1424            return false;
1425    }
1426    return true;
1427}
1428
1429// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1430bool
1431EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1432{
1433#if 0
1434    // ARM pseudo code...
1435    if (ConditionPassed())
1436    {
1437        EncodingSpecificOperations();
1438        BXWritePC(R[m]);
1439    }
1440#endif
1441
1442    if (ConditionPassed(opcode))
1443    {
1444        EmulateInstruction::Context context;
1445        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1446        uint32_t Rm; // the register with the target address
1447        switch (encoding) {
1448        case eEncodingT1:
1449            Rm = Bits32(opcode, 6, 3);
1450            if (InITBlock() && !LastInITBlock())
1451                return false;
1452            break;
1453        case eEncodingA1:
1454            Rm = Bits32(opcode, 3, 0);
1455            break;
1456        default:
1457            return false;
1458        }
1459        bool success = false;
1460        addr_t target = ReadCoreReg (Rm, &success);
1461        if (!success)
1462            return false;
1463
1464        Register dwarf_reg;
1465        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1466        context.SetRegister (dwarf_reg);
1467        if (!BXWritePC(context, target))
1468            return false;
1469    }
1470    return true;
1471}
1472
1473// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1474// address and instruction set specified by a register as though it were a BX instruction.
1475//
1476// TODO: Emulate Jazelle architecture?
1477//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1478bool
1479EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1480{
1481#if 0
1482    // ARM pseudo code...
1483    if (ConditionPassed())
1484    {
1485        EncodingSpecificOperations();
1486        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1487            BXWritePC(R[m]);
1488        else
1489            if JazelleAcceptsExecution() then
1490                SwitchToJazelleExecution();
1491            else
1492                SUBARCHITECTURE_DEFINED handler call;
1493    }
1494#endif
1495
1496    if (ConditionPassed(opcode))
1497    {
1498        EmulateInstruction::Context context;
1499        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1500        uint32_t Rm; // the register with the target address
1501        switch (encoding) {
1502        case eEncodingT1:
1503            Rm = Bits32(opcode, 19, 16);
1504            if (BadReg(Rm))
1505                return false;
1506            if (InITBlock() && !LastInITBlock())
1507                return false;
1508            break;
1509        case eEncodingA1:
1510            Rm = Bits32(opcode, 3, 0);
1511            if (Rm == 15)
1512                return false;
1513            break;
1514        default:
1515            return false;
1516        }
1517        bool success = false;
1518        addr_t target = ReadCoreReg (Rm, &success);
1519        if (!success)
1520            return false;
1521
1522        Register dwarf_reg;
1523        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1524        context.SetRegister (dwarf_reg);
1525        if (!BXWritePC(context, target))
1526            return false;
1527    }
1528    return true;
1529}
1530
1531// Set r7 to point to some ip offset.
1532// SUB (immediate)
1533bool
1534EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1535{
1536#if 0
1537    // ARM pseudo code...
1538    if (ConditionPassed())
1539    {
1540        EncodingSpecificOperations();
1541        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1542        if d == 15 then // Can only occur for ARM encoding
1543           ALUWritePC(result); // setflags is always FALSE here
1544        else
1545            R[d] = result;
1546            if setflags then
1547                APSR.N = result<31>;
1548                APSR.Z = IsZeroBit(result);
1549                APSR.C = carry;
1550                APSR.V = overflow;
1551    }
1552#endif
1553
1554    if (ConditionPassed(opcode))
1555    {
1556        bool success = false;
1557        const addr_t ip = ReadCoreReg (12, &success);
1558        if (!success)
1559            return false;
1560        uint32_t imm32;
1561        switch (encoding) {
1562        case eEncodingA1:
1563            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1564            break;
1565        default:
1566            return false;
1567        }
1568        addr_t ip_offset = imm32;
1569        addr_t addr = ip - ip_offset; // the adjusted ip value
1570
1571        EmulateInstruction::Context context;
1572        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1573        Register dwarf_reg;
1574        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
1575        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1576
1577        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1578            return false;
1579    }
1580    return true;
1581}
1582
1583// Set ip to point to some stack offset.
1584// SUB (SP minus immediate)
1585bool
1586EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1587{
1588#if 0
1589    // ARM pseudo code...
1590    if (ConditionPassed())
1591    {
1592        EncodingSpecificOperations();
1593        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1594        if d == 15 then // Can only occur for ARM encoding
1595           ALUWritePC(result); // setflags is always FALSE here
1596        else
1597            R[d] = result;
1598            if setflags then
1599                APSR.N = result<31>;
1600                APSR.Z = IsZeroBit(result);
1601                APSR.C = carry;
1602                APSR.V = overflow;
1603    }
1604#endif
1605
1606    if (ConditionPassed(opcode))
1607    {
1608        bool success = false;
1609        const addr_t sp = ReadCoreReg (SP_REG, &success);
1610        if (!success)
1611            return false;
1612        uint32_t imm32;
1613        switch (encoding) {
1614        case eEncodingA1:
1615            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1616            break;
1617        default:
1618            return false;
1619        }
1620        addr_t sp_offset = imm32;
1621        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1622
1623        EmulateInstruction::Context context;
1624        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1625        Register dwarf_reg;
1626        dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1627        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1628
1629        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1630            return false;
1631    }
1632    return true;
1633}
1634
1635// This instruction subtracts an immediate value from the SP value, and writes
1636// the result to the destination register.
1637//
1638// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1639bool
1640EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1641{
1642#if 0
1643    // ARM pseudo code...
1644    if (ConditionPassed())
1645    {
1646        EncodingSpecificOperations();
1647        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1648        if d == 15 then        // Can only occur for ARM encoding
1649           ALUWritePC(result); // setflags is always FALSE here
1650        else
1651            R[d] = result;
1652            if setflags then
1653                APSR.N = result<31>;
1654                APSR.Z = IsZeroBit(result);
1655                APSR.C = carry;
1656                APSR.V = overflow;
1657    }
1658#endif
1659
1660    bool success = false;
1661    if (ConditionPassed(opcode))
1662    {
1663        const addr_t sp = ReadCoreReg (SP_REG, &success);
1664        if (!success)
1665            return false;
1666
1667        uint32_t Rd;
1668        bool setflags;
1669        uint32_t imm32;
1670        switch (encoding) {
1671        case eEncodingT1:
1672            Rd = 13;
1673            setflags = false;
1674            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1675            break;
1676        case eEncodingT2:
1677            Rd = Bits32(opcode, 11, 8);
1678            setflags = BitIsSet(opcode, 20);
1679            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1680            if (Rd == 15 && setflags)
1681                return EmulateCMPImm(opcode, eEncodingT2);
1682            if (Rd == 15 && !setflags)
1683                return false;
1684            break;
1685        case eEncodingT3:
1686            Rd = Bits32(opcode, 11, 8);
1687            setflags = false;
1688            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1689            if (Rd == 15)
1690                return false;
1691            break;
1692        case eEncodingA1:
1693            Rd = Bits32(opcode, 15, 12);
1694            setflags = BitIsSet(opcode, 20);
1695            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1696            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1697            // TODO: Emulate SUBS PC, LR and related instructions.
1698            if (Rd == 15 && setflags)
1699                return false;
1700            break;
1701        default:
1702            return false;
1703        }
1704        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1705
1706        EmulateInstruction::Context context;
1707        if (Rd == 13)
1708        {
1709            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1710                                     // value gets passed down to context.SetImmediateSigned.
1711            context.type = EmulateInstruction::eContextAdjustStackPointer;
1712            context.SetImmediateSigned (-imm64); // the stack pointer offset
1713        }
1714        else
1715        {
1716            context.type = EmulateInstruction::eContextImmediate;
1717            context.SetNoArgs ();
1718        }
1719
1720        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1721            return false;
1722    }
1723    return true;
1724}
1725
1726// A store operation to the stack that also updates the SP.
1727bool
1728EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1729{
1730#if 0
1731    // ARM pseudo code...
1732    if (ConditionPassed())
1733    {
1734        EncodingSpecificOperations();
1735        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1736        address = if index then offset_addr else R[n];
1737        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1738        if wback then R[n] = offset_addr;
1739    }
1740#endif
1741
1742    bool success = false;
1743
1744    if (ConditionPassed(opcode))
1745    {
1746        const uint32_t addr_byte_size = GetAddressByteSize();
1747        const addr_t sp = ReadCoreReg (SP_REG, &success);
1748        if (!success)
1749            return false;
1750        uint32_t Rt; // the source register
1751        uint32_t imm12;
1752        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1753
1754        bool index;
1755        bool add;
1756        bool wback;
1757        switch (encoding) {
1758        case eEncodingA1:
1759            Rt = Bits32(opcode, 15, 12);
1760            imm12 = Bits32(opcode, 11, 0);
1761            Rn = Bits32 (opcode, 19, 16);
1762
1763            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1764                return false;
1765
1766            index = BitIsSet (opcode, 24);
1767            add = BitIsSet (opcode, 23);
1768            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1769
1770            if (wback && ((Rn == 15) || (Rn == Rt)))
1771                return false;
1772            break;
1773        default:
1774            return false;
1775        }
1776        addr_t offset_addr;
1777        if (add)
1778            offset_addr = sp + imm12;
1779        else
1780            offset_addr = sp - imm12;
1781
1782        addr_t addr;
1783        if (index)
1784            addr = offset_addr;
1785        else
1786            addr = sp;
1787
1788        EmulateInstruction::Context context;
1789        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1790        Register sp_reg;
1791        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1792        context.SetRegisterPlusOffset (sp_reg, addr - sp);
1793        if (Rt != 15)
1794        {
1795            uint32_t reg_value = ReadCoreReg(Rt, &success);
1796            if (!success)
1797                return false;
1798            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1799                return false;
1800        }
1801        else
1802        {
1803            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1804            if (!success)
1805                return false;
1806            if (!MemUWrite (context, addr, pc, addr_byte_size))
1807                return false;
1808        }
1809
1810
1811        if (wback)
1812        {
1813            context.type = EmulateInstruction::eContextAdjustStackPointer;
1814            context.SetImmediateSigned (addr - sp);
1815            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1816                return false;
1817        }
1818    }
1819    return true;
1820}
1821
1822// Vector Push stores multiple extension registers to the stack.
1823// It also updates SP to point to the start of the stored data.
1824bool
1825EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1826{
1827#if 0
1828    // ARM pseudo code...
1829    if (ConditionPassed())
1830    {
1831        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1832        address = SP - imm32;
1833        SP = SP - imm32;
1834        if single_regs then
1835            for r = 0 to regs-1
1836                MemA[address,4] = S[d+r]; address = address+4;
1837        else
1838            for r = 0 to regs-1
1839                // Store as two word-aligned words in the correct order for current endianness.
1840                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1841                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1842                address = address+8;
1843    }
1844#endif
1845
1846    bool success = false;
1847
1848    if (ConditionPassed(opcode))
1849    {
1850        const uint32_t addr_byte_size = GetAddressByteSize();
1851        const addr_t sp = ReadCoreReg (SP_REG, &success);
1852        if (!success)
1853            return false;
1854        bool single_regs;
1855        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1856        uint32_t imm32; // stack offset
1857        uint32_t regs;  // number of registers
1858        switch (encoding) {
1859        case eEncodingT1:
1860        case eEncodingA1:
1861            single_regs = false;
1862            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1863            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1864            // If UInt(imm8) is odd, see "FSTMX".
1865            regs = Bits32(opcode, 7, 0) / 2;
1866            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1867            if (regs == 0 || regs > 16 || (d + regs) > 32)
1868                return false;
1869            break;
1870        case eEncodingT2:
1871        case eEncodingA2:
1872            single_regs = true;
1873            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1874            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1875            regs = Bits32(opcode, 7, 0);
1876            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1877            if (regs == 0 || regs > 16 || (d + regs) > 32)
1878                return false;
1879            break;
1880        default:
1881            return false;
1882        }
1883        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1884        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1885        addr_t sp_offset = imm32;
1886        addr_t addr = sp - sp_offset;
1887        uint32_t i;
1888
1889        EmulateInstruction::Context context;
1890        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1891        Register dwarf_reg;
1892        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1893        Register sp_reg;
1894        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1895        for (i=0; i<regs; ++i)
1896        {
1897            dwarf_reg.num = start_reg + d + i;
1898            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1899            // uint64_t to accommodate 64-bit registers.
1900            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1901            if (!success)
1902                return false;
1903            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1904                return false;
1905            addr += reg_byte_size;
1906        }
1907
1908        context.type = EmulateInstruction::eContextAdjustStackPointer;
1909        context.SetImmediateSigned (-sp_offset);
1910
1911        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1912            return false;
1913    }
1914    return true;
1915}
1916
1917// Vector Pop loads multiple extension registers from the stack.
1918// It also updates SP to point just above the loaded data.
1919bool
1920EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
1921{
1922#if 0
1923    // ARM pseudo code...
1924    if (ConditionPassed())
1925    {
1926        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1927        address = SP;
1928        SP = SP + imm32;
1929        if single_regs then
1930            for r = 0 to regs-1
1931                S[d+r] = MemA[address,4]; address = address+4;
1932        else
1933            for r = 0 to regs-1
1934                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1935                // Combine the word-aligned words in the correct order for current endianness.
1936                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1937    }
1938#endif
1939
1940    bool success = false;
1941
1942    if (ConditionPassed(opcode))
1943    {
1944        const uint32_t addr_byte_size = GetAddressByteSize();
1945        const addr_t sp = ReadCoreReg (SP_REG, &success);
1946        if (!success)
1947            return false;
1948        bool single_regs;
1949        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1950        uint32_t imm32; // stack offset
1951        uint32_t regs;  // number of registers
1952        switch (encoding) {
1953        case eEncodingT1:
1954        case eEncodingA1:
1955            single_regs = false;
1956            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1957            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1958            // If UInt(imm8) is odd, see "FLDMX".
1959            regs = Bits32(opcode, 7, 0) / 2;
1960            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1961            if (regs == 0 || regs > 16 || (d + regs) > 32)
1962                return false;
1963            break;
1964        case eEncodingT2:
1965        case eEncodingA2:
1966            single_regs = true;
1967            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1968            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1969            regs = Bits32(opcode, 7, 0);
1970            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1971            if (regs == 0 || regs > 16 || (d + regs) > 32)
1972                return false;
1973            break;
1974        default:
1975            return false;
1976        }
1977        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1978        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1979        addr_t sp_offset = imm32;
1980        addr_t addr = sp;
1981        uint32_t i;
1982        uint64_t data; // uint64_t to accomodate 64-bit registers.
1983
1984        EmulateInstruction::Context context;
1985        context.type = EmulateInstruction::eContextPopRegisterOffStack;
1986        Register dwarf_reg;
1987        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1988        Register sp_reg;
1989        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1990        for (i=0; i<regs; ++i)
1991        {
1992            dwarf_reg.num = start_reg + d + i;
1993            context.SetRegisterPlusOffset (sp_reg, addr - sp);
1994            data = MemARead(context, addr, reg_byte_size, 0, &success);
1995            if (!success)
1996                return false;
1997            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
1998                return false;
1999            addr += reg_byte_size;
2000        }
2001
2002        context.type = EmulateInstruction::eContextAdjustStackPointer;
2003        context.SetImmediateSigned (sp_offset);
2004
2005        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2006            return false;
2007    }
2008    return true;
2009}
2010
2011// SVC (previously SWI)
2012bool
2013EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2014{
2015#if 0
2016    // ARM pseudo code...
2017    if (ConditionPassed())
2018    {
2019        EncodingSpecificOperations();
2020        CallSupervisor();
2021    }
2022#endif
2023
2024    bool success = false;
2025
2026    if (ConditionPassed(opcode))
2027    {
2028        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2029        addr_t lr; // next instruction address
2030        if (!success)
2031            return false;
2032        uint32_t imm32; // the immediate constant
2033        uint32_t mode;  // ARM or Thumb mode
2034        switch (encoding) {
2035        case eEncodingT1:
2036            lr = (pc + 2) | 1u; // return address
2037            imm32 = Bits32(opcode, 7, 0);
2038            mode = eModeThumb;
2039            break;
2040        case eEncodingA1:
2041            lr = pc + 4; // return address
2042            imm32 = Bits32(opcode, 23, 0);
2043            mode = eModeARM;
2044            break;
2045        default:
2046            return false;
2047        }
2048
2049        EmulateInstruction::Context context;
2050        context.type = EmulateInstruction::eContextSupervisorCall;
2051        context.SetModeAndImmediate (mode, imm32);
2052        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2053            return false;
2054    }
2055    return true;
2056}
2057
2058// If Then makes up to four following instructions (the IT block) conditional.
2059bool
2060EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2061{
2062#if 0
2063    // ARM pseudo code...
2064    EncodingSpecificOperations();
2065    ITSTATE.IT<7:0> = firstcond:mask;
2066#endif
2067
2068    m_it_session.InitIT(Bits32(opcode, 7, 0));
2069    return true;
2070}
2071
2072// Branch causes a branch to a target address.
2073bool
2074EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2075{
2076#if 0
2077    // ARM pseudo code...
2078    if (ConditionPassed())
2079    {
2080        EncodingSpecificOperations();
2081        BranchWritePC(PC + imm32);
2082    }
2083#endif
2084
2085    bool success = false;
2086
2087    if (ConditionPassed(opcode))
2088    {
2089        EmulateInstruction::Context context;
2090        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2091        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2092        if (!success)
2093            return false;
2094        addr_t target; // target address
2095        int32_t imm32; // PC-relative offset
2096        switch (encoding) {
2097        case eEncodingT1:
2098            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2099            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2100            target = pc + imm32;
2101            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2102            break;
2103        case eEncodingT2:
2104            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2105            target = pc + imm32;
2106            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2107            break;
2108        case eEncodingT3:
2109            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2110            {
2111            uint32_t S = Bit32(opcode, 26);
2112            uint32_t imm6 = Bits32(opcode, 21, 16);
2113            uint32_t J1 = Bit32(opcode, 13);
2114            uint32_t J2 = Bit32(opcode, 11);
2115            uint32_t imm11 = Bits32(opcode, 10, 0);
2116            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2117            imm32 = llvm::SignExtend32<21>(imm21);
2118            target = pc + imm32;
2119            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2120            break;
2121            }
2122        case eEncodingT4:
2123            {
2124            uint32_t S = Bit32(opcode, 26);
2125            uint32_t imm10 = Bits32(opcode, 25, 16);
2126            uint32_t J1 = Bit32(opcode, 13);
2127            uint32_t J2 = Bit32(opcode, 11);
2128            uint32_t imm11 = Bits32(opcode, 10, 0);
2129            uint32_t I1 = !(J1 ^ S);
2130            uint32_t I2 = !(J2 ^ S);
2131            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2132            imm32 = llvm::SignExtend32<25>(imm25);
2133            target = pc + imm32;
2134            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2135            break;
2136            }
2137        case eEncodingA1:
2138            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2139            target = pc + imm32;
2140            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
2141            break;
2142        default:
2143            return false;
2144        }
2145        if (!BranchWritePC(context, target))
2146            return false;
2147    }
2148    return true;
2149}
2150
2151// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2152// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2153// CBNZ, CBZ
2154bool
2155EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2156{
2157#if 0
2158    // ARM pseudo code...
2159    EncodingSpecificOperations();
2160    if nonzero ^ IsZero(R[n]) then
2161        BranchWritePC(PC + imm32);
2162#endif
2163
2164    bool success = false;
2165
2166    // Read the register value from the operand register Rn.
2167    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2168    if (!success)
2169        return false;
2170
2171    EmulateInstruction::Context context;
2172    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2173    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2174    if (!success)
2175        return false;
2176
2177    addr_t target;  // target address
2178    uint32_t imm32; // PC-relative offset to branch forward
2179    bool nonzero;
2180    switch (encoding) {
2181    case eEncodingT1:
2182        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2183        nonzero = BitIsSet(opcode, 11);
2184        target = pc + imm32;
2185        context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2186        break;
2187    default:
2188        return false;
2189    }
2190    if (nonzero ^ (reg_val == 0))
2191        if (!BranchWritePC(context, target))
2192            return false;
2193
2194    return true;
2195}
2196
2197// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2198// A base register provides a pointer to the table, and a second register supplies an index into the table.
2199// The branch length is twice the value of the byte returned from the table.
2200//
2201// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2202// A base register provides a pointer to the table, and a second register supplies an index into the table.
2203// The branch length is twice the value of the halfword returned from the table.
2204// TBB, TBH
2205bool
2206EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2207{
2208#if 0
2209    // ARM pseudo code...
2210    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2211    if is_tbh then
2212        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2213    else
2214        halfwords = UInt(MemU[R[n]+R[m], 1]);
2215    BranchWritePC(PC + 2*halfwords);
2216#endif
2217
2218    bool success = false;
2219
2220    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2221    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2222    bool is_tbh;     // true if table branch halfword
2223    switch (encoding) {
2224    case eEncodingT1:
2225        Rn = Bits32(opcode, 19, 16);
2226        Rm = Bits32(opcode, 3, 0);
2227        is_tbh = BitIsSet(opcode, 4);
2228        if (Rn == 13 || BadReg(Rm))
2229            return false;
2230        if (InITBlock() && !LastInITBlock())
2231            return false;
2232        break;
2233    default:
2234        return false;
2235    }
2236
2237    // Read the address of the table from the operand register Rn.
2238    // The PC can be used, in which case the table immediately follows this instruction.
2239    uint32_t base = ReadCoreReg(Rm, &success);
2240    if (!success)
2241        return false;
2242
2243    // the table index
2244    uint32_t index = ReadCoreReg(Rm, &success);
2245    if (!success)
2246        return false;
2247
2248    // the offsetted table address
2249    addr_t addr = base + (is_tbh ? index*2 : index);
2250
2251    // PC-relative offset to branch forward
2252    EmulateInstruction::Context context;
2253    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2254    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2255    if (!success)
2256        return false;
2257
2258    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2259    if (!success)
2260        return false;
2261
2262    // target address
2263    addr_t target = pc + offset;
2264    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2265    context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
2266
2267    if (!BranchWritePC(context, target))
2268        return false;
2269
2270    return true;
2271}
2272
2273// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2274// It can optionally update the condition flags based on the result.
2275bool
2276EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2277{
2278#if 0
2279    if ConditionPassed() then
2280        EncodingSpecificOperations();
2281        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2282        R[d] = result;
2283        if setflags then
2284            APSR.N = result<31>;
2285            APSR.Z = IsZeroBit(result);
2286            APSR.C = carry;
2287            APSR.V = overflow;
2288#endif
2289
2290    bool success = false;
2291
2292    if (ConditionPassed(opcode))
2293    {
2294        uint32_t d;
2295        uint32_t n;
2296        bool setflags;
2297        uint32_t imm32;
2298        uint32_t carry_out;
2299
2300        //EncodingSpecificOperations();
2301        switch (encoding)
2302        {
2303            case eEncodingT1:
2304                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2305                d = Bits32 (opcode, 2, 0);
2306                n = Bits32 (opcode, 5, 3);
2307                setflags = !InITBlock();
2308                imm32 = Bits32 (opcode, 8,6);
2309
2310                break;
2311
2312            case eEncodingT2:
2313                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2314                d = Bits32 (opcode, 10, 8);
2315                n = Bits32 (opcode, 10, 8);
2316                setflags = !InITBlock();
2317                imm32 = Bits32 (opcode, 7, 0);
2318
2319                break;
2320
2321            case eEncodingT3:
2322                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2323                // if Rn == '1101' then SEE ADD (SP plus immediate);
2324                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2325                d = Bits32 (opcode, 11, 8);
2326                n = Bits32 (opcode, 19, 16);
2327                setflags = BitIsSet (opcode, 20);
2328                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2329
2330                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2331                if (BadReg (d) || (n == 15))
2332                    return false;
2333
2334                break;
2335
2336            case eEncodingT4:
2337            {
2338                // if Rn == '1111' then SEE ADR;
2339                // if Rn == '1101' then SEE ADD (SP plus immediate);
2340                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2341                d = Bits32 (opcode, 11, 8);
2342                n = Bits32 (opcode, 19, 16);
2343                setflags = false;
2344                uint32_t i = Bit32 (opcode, 26);
2345                uint32_t imm3 = Bits32 (opcode, 14, 12);
2346                uint32_t imm8 = Bits32 (opcode, 7, 0);
2347                imm32 = (i << 11) | (imm3 << 8) | imm8;
2348
2349                // if BadReg(d) then UNPREDICTABLE;
2350                if (BadReg (d))
2351                    return false;
2352
2353                break;
2354            }
2355            default:
2356                return false;
2357        }
2358
2359        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2360        if (!success)
2361            return false;
2362
2363        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2364        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2365
2366        Register reg_n;
2367        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2368
2369        EmulateInstruction::Context context;
2370        context.type = eContextAddition;
2371        context.SetRegisterPlusOffset (reg_n, imm32);
2372
2373        //R[d] = result;
2374        //if setflags then
2375            //APSR.N = result<31>;
2376            //APSR.Z = IsZeroBit(result);
2377            //APSR.C = carry;
2378            //APSR.V = overflow;
2379        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2380            return false;
2381
2382    }
2383    return true;
2384}
2385
2386// This instruction adds an immediate value to a register value, and writes the result to the destination
2387// register.  It can optionally update the condition flags based on the result.
2388bool
2389EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2390{
2391#if 0
2392    // ARM pseudo code...
2393    if ConditionPassed() then
2394        EncodingSpecificOperations();
2395        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2396        if d == 15 then
2397            ALUWritePC(result); // setflags is always FALSE here
2398        else
2399            R[d] = result;
2400            if setflags then
2401                APSR.N = result<31>;
2402                APSR.Z = IsZeroBit(result);
2403                APSR.C = carry;
2404                APSR.V = overflow;
2405#endif
2406
2407    bool success = false;
2408
2409    if (ConditionPassed(opcode))
2410    {
2411        uint32_t Rd, Rn;
2412        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2413        bool setflags;
2414        switch (encoding)
2415        {
2416        case eEncodingA1:
2417            Rd = Bits32(opcode, 15, 12);
2418            Rn = Bits32(opcode, 19, 16);
2419            setflags = BitIsSet(opcode, 20);
2420            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2421            break;
2422        default:
2423            return false;
2424        }
2425
2426        // Read the first operand.
2427        uint32_t val1 = ReadCoreReg(Rn, &success);
2428        if (!success)
2429            return false;
2430
2431        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2432
2433        EmulateInstruction::Context context;
2434        context.type = EmulateInstruction::eContextImmediate;
2435        context.SetNoArgs ();
2436
2437        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2438            return false;
2439    }
2440    return true;
2441}
2442
2443// This instruction adds a register value and an optionally-shifted register value, and writes the result
2444// to the destination register. It can optionally update the condition flags based on the result.
2445bool
2446EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2447{
2448#if 0
2449    // ARM pseudo code...
2450    if ConditionPassed() then
2451        EncodingSpecificOperations();
2452        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2453        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2454        if d == 15 then
2455            ALUWritePC(result); // setflags is always FALSE here
2456        else
2457            R[d] = result;
2458            if setflags then
2459                APSR.N = result<31>;
2460                APSR.Z = IsZeroBit(result);
2461                APSR.C = carry;
2462                APSR.V = overflow;
2463#endif
2464
2465    bool success = false;
2466
2467    if (ConditionPassed(opcode))
2468    {
2469        uint32_t Rd, Rn, Rm;
2470        ARM_ShifterType shift_t;
2471        uint32_t shift_n; // the shift applied to the value read from Rm
2472        bool setflags;
2473        switch (encoding)
2474        {
2475        case eEncodingT1:
2476            Rd = Bits32(opcode, 2, 0);
2477            Rn = Bits32(opcode, 5, 3);
2478            Rm = Bits32(opcode, 8, 6);
2479            setflags = !InITBlock();
2480            shift_t = SRType_LSL;
2481            shift_n = 0;
2482            break;
2483        case eEncodingT2:
2484            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2485            Rm = Bits32(opcode, 6, 3);
2486            setflags = false;
2487            shift_t = SRType_LSL;
2488            shift_n = 0;
2489            if (Rn == 15 && Rm == 15)
2490                return false;
2491            if (Rd == 15 && InITBlock() && !LastInITBlock())
2492                return false;
2493            break;
2494        case eEncodingA1:
2495            Rd = Bits32(opcode, 15, 12);
2496            Rn = Bits32(opcode, 19, 16);
2497            Rm = Bits32(opcode, 3, 0);
2498            setflags = BitIsSet(opcode, 20);
2499            shift_n = DecodeImmShiftARM(opcode, shift_t);
2500            break;
2501        default:
2502            return false;
2503        }
2504
2505        // Read the first operand.
2506        uint32_t val1 = ReadCoreReg(Rn, &success);
2507        if (!success)
2508            return false;
2509
2510        // Read the second operand.
2511        uint32_t val2 = ReadCoreReg(Rm, &success);
2512        if (!success)
2513            return false;
2514
2515        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2516        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2517
2518        EmulateInstruction::Context context;
2519        context.type = EmulateInstruction::eContextAddition;
2520        Register op1_reg;
2521        Register op2_reg;
2522        op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
2523        op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
2524        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2525
2526        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2527            return false;
2528    }
2529    return true;
2530}
2531
2532// Compare Negative (immediate) adds a register value and an immediate value.
2533// It updates the condition flags based on the result, and discards the result.
2534bool
2535EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2536{
2537#if 0
2538    // ARM pseudo code...
2539    if ConditionPassed() then
2540        EncodingSpecificOperations();
2541        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2542        APSR.N = result<31>;
2543        APSR.Z = IsZeroBit(result);
2544        APSR.C = carry;
2545        APSR.V = overflow;
2546#endif
2547
2548    bool success = false;
2549
2550    uint32_t Rn; // the first operand
2551    uint32_t imm32; // the immediate value to be compared with
2552    switch (encoding) {
2553    case eEncodingT1:
2554        Rn = Bits32(opcode, 19, 16);
2555        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2556        if (Rn == 15)
2557            return false;
2558        break;
2559    case eEncodingA1:
2560        Rn = Bits32(opcode, 19, 16);
2561        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2562        break;
2563    default:
2564        return false;
2565    }
2566    // Read the register value from the operand register Rn.
2567    uint32_t reg_val = ReadCoreReg(Rn, &success);
2568    if (!success)
2569        return false;
2570
2571    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2572
2573    EmulateInstruction::Context context;
2574    context.type = EmulateInstruction::eContextImmediate;
2575    context.SetNoArgs ();
2576    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2577        return false;
2578
2579    return true;
2580}
2581
2582// Compare Negative (register) adds a register value and an optionally-shifted register value.
2583// It updates the condition flags based on the result, and discards the result.
2584bool
2585EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2586{
2587#if 0
2588    // ARM pseudo code...
2589    if ConditionPassed() then
2590        EncodingSpecificOperations();
2591        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2592        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2593        APSR.N = result<31>;
2594        APSR.Z = IsZeroBit(result);
2595        APSR.C = carry;
2596        APSR.V = overflow;
2597#endif
2598
2599    bool success = false;
2600
2601    uint32_t Rn; // the first operand
2602    uint32_t Rm; // the second operand
2603    ARM_ShifterType shift_t;
2604    uint32_t shift_n; // the shift applied to the value read from Rm
2605    switch (encoding) {
2606    case eEncodingT1:
2607        Rn = Bits32(opcode, 2, 0);
2608        Rm = Bits32(opcode, 5, 3);
2609        shift_t = SRType_LSL;
2610        shift_n = 0;
2611        break;
2612    case eEncodingT2:
2613        Rn = Bits32(opcode, 19, 16);
2614        Rm = Bits32(opcode, 3, 0);
2615        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2616        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2617        if (Rn == 15 || BadReg(Rm))
2618            return false;
2619        break;
2620    case eEncodingA1:
2621        Rn = Bits32(opcode, 19, 16);
2622        Rm = Bits32(opcode, 3, 0);
2623        shift_n = DecodeImmShiftARM(opcode, shift_t);
2624        break;
2625    default:
2626        return false;
2627    }
2628    // Read the register value from register Rn.
2629    uint32_t val1 = ReadCoreReg(Rn, &success);
2630    if (!success)
2631        return false;
2632
2633    // Read the register value from register Rm.
2634    uint32_t val2 = ReadCoreReg(Rm, &success);
2635    if (!success)
2636        return false;
2637
2638    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2639    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2640
2641    EmulateInstruction::Context context;
2642    context.type = EmulateInstruction::eContextImmediate;
2643    context.SetNoArgs();
2644    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2645        return false;
2646
2647    return true;
2648}
2649
2650// Compare (immediate) subtracts an immediate value from a register value.
2651// It updates the condition flags based on the result, and discards the result.
2652bool
2653EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2654{
2655#if 0
2656    // ARM pseudo code...
2657    if ConditionPassed() then
2658        EncodingSpecificOperations();
2659        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2660        APSR.N = result<31>;
2661        APSR.Z = IsZeroBit(result);
2662        APSR.C = carry;
2663        APSR.V = overflow;
2664#endif
2665
2666    bool success = false;
2667
2668    uint32_t Rn; // the first operand
2669    uint32_t imm32; // the immediate value to be compared with
2670    switch (encoding) {
2671    case eEncodingT1:
2672        Rn = Bits32(opcode, 10, 8);
2673        imm32 = Bits32(opcode, 7, 0);
2674        break;
2675    case eEncodingT2:
2676        Rn = Bits32(opcode, 19, 16);
2677        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2678        if (Rn == 15)
2679            return false;
2680        break;
2681    case eEncodingA1:
2682        Rn = Bits32(opcode, 19, 16);
2683        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2684        break;
2685    default:
2686        return false;
2687    }
2688    // Read the register value from the operand register Rn.
2689    uint32_t reg_val = ReadCoreReg(Rn, &success);
2690    if (!success)
2691        return false;
2692
2693    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2694
2695    EmulateInstruction::Context context;
2696    context.type = EmulateInstruction::eContextImmediate;
2697    context.SetNoArgs ();
2698    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2699        return false;
2700
2701    return true;
2702}
2703
2704// Compare (register) subtracts an optionally-shifted register value from a register value.
2705// It updates the condition flags based on the result, and discards the result.
2706bool
2707EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2708{
2709#if 0
2710    // ARM pseudo code...
2711    if ConditionPassed() then
2712        EncodingSpecificOperations();
2713        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2714        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2715        APSR.N = result<31>;
2716        APSR.Z = IsZeroBit(result);
2717        APSR.C = carry;
2718        APSR.V = overflow;
2719#endif
2720
2721    bool success = false;
2722
2723    uint32_t Rn; // the first operand
2724    uint32_t Rm; // the second operand
2725    ARM_ShifterType shift_t;
2726    uint32_t shift_n; // the shift applied to the value read from Rm
2727    switch (encoding) {
2728    case eEncodingT1:
2729        Rn = Bits32(opcode, 2, 0);
2730        Rm = Bits32(opcode, 5, 3);
2731        shift_t = SRType_LSL;
2732        shift_n = 0;
2733        break;
2734    case eEncodingT2:
2735        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2736        Rm = Bits32(opcode, 6, 3);
2737        shift_t = SRType_LSL;
2738        shift_n = 0;
2739        if (Rn < 8 && Rm < 8)
2740            return false;
2741        if (Rn == 15 || Rm == 15)
2742            return false;
2743        break;
2744    case eEncodingA1:
2745        Rn = Bits32(opcode, 19, 16);
2746        Rm = Bits32(opcode, 3, 0);
2747        shift_n = DecodeImmShiftARM(opcode, shift_t);
2748        break;
2749    default:
2750        return false;
2751    }
2752    // Read the register value from register Rn.
2753    uint32_t val1 = ReadCoreReg(Rn, &success);
2754    if (!success)
2755        return false;
2756
2757    // Read the register value from register Rm.
2758    uint32_t val2 = ReadCoreReg(Rm, &success);
2759    if (!success)
2760        return false;
2761
2762    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2763    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2764
2765    EmulateInstruction::Context context;
2766    context.type = EmulateInstruction::eContextImmediate;
2767    context.SetNoArgs();
2768    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2769        return false;
2770
2771    return true;
2772}
2773
2774// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2775// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2776// optionally update the condition flags based on the result.
2777bool
2778EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2779{
2780#if 0
2781    // ARM pseudo code...
2782    if ConditionPassed() then
2783        EncodingSpecificOperations();
2784        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2785        if d == 15 then         // Can only occur for ARM encoding
2786            ALUWritePC(result); // setflags is always FALSE here
2787        else
2788            R[d] = result;
2789            if setflags then
2790                APSR.N = result<31>;
2791                APSR.Z = IsZeroBit(result);
2792                APSR.C = carry;
2793                // APSR.V unchanged
2794#endif
2795
2796    return EmulateShiftImm (opcode, encoding, SRType_ASR);
2797}
2798
2799// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2800// shifting in copies of its sign bit, and writes the result to the destination register.
2801// The variable number of bits is read from the bottom byte of a register. It can optionally update
2802// the condition flags based on the result.
2803bool
2804EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2805{
2806#if 0
2807    // ARM pseudo code...
2808    if ConditionPassed() then
2809        EncodingSpecificOperations();
2810        shift_n = UInt(R[m]<7:0>);
2811        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2812        R[d] = result;
2813        if setflags then
2814            APSR.N = result<31>;
2815            APSR.Z = IsZeroBit(result);
2816            APSR.C = carry;
2817            // APSR.V unchanged
2818#endif
2819
2820    return EmulateShiftReg (opcode, encoding, SRType_ASR);
2821}
2822
2823// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2824// shifting in zeros, and writes the result to the destination register.  It can optionally
2825// update the condition flags based on the result.
2826bool
2827EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2828{
2829#if 0
2830    // ARM pseudo code...
2831    if ConditionPassed() then
2832        EncodingSpecificOperations();
2833        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2834        if d == 15 then         // Can only occur for ARM encoding
2835            ALUWritePC(result); // setflags is always FALSE here
2836        else
2837            R[d] = result;
2838            if setflags then
2839                APSR.N = result<31>;
2840                APSR.Z = IsZeroBit(result);
2841                APSR.C = carry;
2842                // APSR.V unchanged
2843#endif
2844
2845    return EmulateShiftImm (opcode, encoding, SRType_LSL);
2846}
2847
2848// Logical Shift Left (register) shifts a register value left by a variable number of bits,
2849// shifting in zeros, and writes the result to the destination register.  The variable number
2850// of bits is read from the bottom byte of a register. It can optionally update the condition
2851// flags based on the result.
2852bool
2853EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
2854{
2855#if 0
2856    // ARM pseudo code...
2857    if ConditionPassed() then
2858        EncodingSpecificOperations();
2859        shift_n = UInt(R[m]<7:0>);
2860        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2861        R[d] = result;
2862        if setflags then
2863            APSR.N = result<31>;
2864            APSR.Z = IsZeroBit(result);
2865            APSR.C = carry;
2866            // APSR.V unchanged
2867#endif
2868
2869    return EmulateShiftReg (opcode, encoding, SRType_LSL);
2870}
2871
2872// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
2873// shifting in zeros, and writes the result to the destination register.  It can optionally
2874// update the condition flags based on the result.
2875bool
2876EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
2877{
2878#if 0
2879    // ARM pseudo code...
2880    if ConditionPassed() then
2881        EncodingSpecificOperations();
2882        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2883        if d == 15 then         // Can only occur for ARM encoding
2884            ALUWritePC(result); // setflags is always FALSE here
2885        else
2886            R[d] = result;
2887            if setflags then
2888                APSR.N = result<31>;
2889                APSR.Z = IsZeroBit(result);
2890                APSR.C = carry;
2891                // APSR.V unchanged
2892#endif
2893
2894    return EmulateShiftImm (opcode, encoding, SRType_LSR);
2895}
2896
2897// Logical Shift Right (register) shifts a register value right by a variable number of bits,
2898// shifting in zeros, and writes the result to the destination register.  The variable number
2899// of bits is read from the bottom byte of a register. It can optionally update the condition
2900// flags based on the result.
2901bool
2902EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
2903{
2904#if 0
2905    // ARM pseudo code...
2906    if ConditionPassed() then
2907        EncodingSpecificOperations();
2908        shift_n = UInt(R[m]<7:0>);
2909        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2910        R[d] = result;
2911        if setflags then
2912            APSR.N = result<31>;
2913            APSR.Z = IsZeroBit(result);
2914            APSR.C = carry;
2915            // APSR.V unchanged
2916#endif
2917
2918    return EmulateShiftReg (opcode, encoding, SRType_LSR);
2919}
2920
2921// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2922// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2923// It can optionally update the condition flags based on the result.
2924bool
2925EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
2926{
2927#if 0
2928    // ARM pseudo code...
2929    if ConditionPassed() then
2930        EncodingSpecificOperations();
2931        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2932        if d == 15 then         // Can only occur for ARM encoding
2933            ALUWritePC(result); // setflags is always FALSE here
2934        else
2935            R[d] = result;
2936            if setflags then
2937                APSR.N = result<31>;
2938                APSR.Z = IsZeroBit(result);
2939                APSR.C = carry;
2940                // APSR.V unchanged
2941#endif
2942
2943    return EmulateShiftImm (opcode, encoding, SRType_ROR);
2944}
2945
2946// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
2947// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2948// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
2949// flags based on the result.
2950bool
2951EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
2952{
2953#if 0
2954    // ARM pseudo code...
2955    if ConditionPassed() then
2956        EncodingSpecificOperations();
2957        shift_n = UInt(R[m]<7:0>);
2958        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2959        R[d] = result;
2960        if setflags then
2961            APSR.N = result<31>;
2962            APSR.Z = IsZeroBit(result);
2963            APSR.C = carry;
2964            // APSR.V unchanged
2965#endif
2966
2967    return EmulateShiftReg (opcode, encoding, SRType_ROR);
2968}
2969
2970// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
2971// with the carry flag shifted into bit [31].
2972//
2973// RRX can optionally update the condition flags based on the result.
2974// In that case, bit [0] is shifted into the carry flag.
2975bool
2976EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
2977{
2978#if 0
2979    // ARM pseudo code...
2980    if ConditionPassed() then
2981        EncodingSpecificOperations();
2982        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
2983        if d == 15 then         // Can only occur for ARM encoding
2984            ALUWritePC(result); // setflags is always FALSE here
2985        else
2986            R[d] = result;
2987            if setflags then
2988                APSR.N = result<31>;
2989                APSR.Z = IsZeroBit(result);
2990                APSR.C = carry;
2991                // APSR.V unchanged
2992#endif
2993
2994    return EmulateShiftImm (opcode, encoding, SRType_RRX);
2995}
2996
2997bool
2998EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
2999{
3000    assert(shift_type == SRType_ASR
3001           || shift_type == SRType_LSL
3002           || shift_type == SRType_LSR
3003           || shift_type == SRType_ROR
3004           || shift_type == SRType_RRX);
3005
3006    bool success = false;
3007
3008    if (ConditionPassed(opcode))
3009    {
3010        uint32_t Rd;    // the destination register
3011        uint32_t Rm;    // the first operand register
3012        uint32_t imm5;  // encoding for the shift amount
3013        uint32_t carry; // the carry bit after the shift operation
3014        bool setflags;
3015
3016        // Special case handling!
3017        // A8.6.139 ROR (immediate) -- Encoding T1
3018        ARMEncoding use_encoding = encoding;
3019        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3020        {
3021            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3022            // have the same decoding of bit fields as the other Thumb2 shift operations.
3023            use_encoding = eEncodingT2;
3024        }
3025
3026        switch (use_encoding) {
3027        case eEncodingT1:
3028            // Due to the above special case handling!
3029            assert(shift_type != SRType_ROR);
3030
3031            Rd = Bits32(opcode, 2, 0);
3032            Rm = Bits32(opcode, 5, 3);
3033            setflags = !InITBlock();
3034            imm5 = Bits32(opcode, 10, 6);
3035            break;
3036        case eEncodingT2:
3037            // A8.6.141 RRX
3038            assert(shift_type != SRType_RRX);
3039
3040            Rd = Bits32(opcode, 11, 8);
3041            Rm = Bits32(opcode, 3, 0);
3042            setflags = BitIsSet(opcode, 20);
3043            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3044            if (BadReg(Rd) || BadReg(Rm))
3045                return false;
3046            break;
3047        case eEncodingA1:
3048            Rd = Bits32(opcode, 15, 12);
3049            Rm = Bits32(opcode, 3, 0);
3050            setflags = BitIsSet(opcode, 20);
3051            imm5 = Bits32(opcode, 11, 7);
3052            break;
3053        default:
3054            return false;
3055        }
3056
3057        // A8.6.139 ROR (immediate)
3058        if (shift_type == SRType_ROR && imm5 == 0)
3059            shift_type = SRType_RRX;
3060
3061        // Get the first operand.
3062        uint32_t value = ReadCoreReg (Rm, &success);
3063        if (!success)
3064            return false;
3065
3066        // Decode the shift amount if not RRX.
3067        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3068
3069        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3070
3071        // The context specifies that an immediate is to be moved into Rd.
3072        EmulateInstruction::Context context;
3073        context.type = EmulateInstruction::eContextImmediate;
3074        context.SetNoArgs ();
3075
3076        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3077            return false;
3078    }
3079    return true;
3080}
3081
3082bool
3083EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3084{
3085    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
3086
3087    bool success = false;
3088
3089    if (ConditionPassed(opcode))
3090    {
3091        uint32_t Rd;    // the destination register
3092        uint32_t Rn;    // the first operand register
3093        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3094        uint32_t carry; // the carry bit after the shift operation
3095        bool setflags;
3096        switch (encoding) {
3097        case eEncodingT1:
3098            Rd = Bits32(opcode, 2, 0);
3099            Rn = Rd;
3100            Rm = Bits32(opcode, 5, 3);
3101            setflags = !InITBlock();
3102            break;
3103        case eEncodingT2:
3104            Rd = Bits32(opcode, 11, 8);
3105            Rn = Bits32(opcode, 19, 16);
3106            Rm = Bits32(opcode, 3, 0);
3107            setflags = BitIsSet(opcode, 20);
3108            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3109                return false;
3110            break;
3111        case eEncodingA1:
3112            Rd = Bits32(opcode, 15, 12);
3113            Rn = Bits32(opcode, 3, 0);
3114            Rm = Bits32(opcode, 11, 8);
3115            setflags = BitIsSet(opcode, 20);
3116            if (Rd == 15 || Rn == 15 || Rm == 15)
3117                return false;
3118            break;
3119        default:
3120            return false;
3121        }
3122
3123        // Get the first operand.
3124        uint32_t value = ReadCoreReg (Rn, &success);
3125        if (!success)
3126            return false;
3127        // Get the Rm register content.
3128        uint32_t val = ReadCoreReg (Rm, &success);
3129        if (!success)
3130            return false;
3131
3132        // Get the shift amount.
3133        uint32_t amt = Bits32(val, 7, 0);
3134
3135        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3136
3137        // The context specifies that an immediate is to be moved into Rd.
3138        EmulateInstruction::Context context;
3139        context.type = EmulateInstruction::eContextImmediate;
3140        context.SetNoArgs ();
3141
3142        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3143            return false;
3144    }
3145    return true;
3146}
3147
3148// LDM loads multiple registers from consecutive memory locations, using an
3149// address from a base register.  Optionally the address just above the highest of those locations
3150// can be written back to the base register.
3151bool
3152EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3153{
3154#if 0
3155    // ARM pseudo code...
3156    if ConditionPassed()
3157        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3158        address = R[n];
3159
3160        for i = 0 to 14
3161            if registers<i> == '1' then
3162                R[i] = MemA[address, 4]; address = address + 4;
3163        if registers<15> == '1' then
3164            LoadWritePC (MemA[address, 4]);
3165
3166        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3167        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3168
3169#endif
3170
3171    bool success = false;
3172
3173    if (ConditionPassed(opcode))
3174    {
3175        uint32_t n;
3176        uint32_t registers = 0;
3177        bool wback;
3178        const uint32_t addr_byte_size = GetAddressByteSize();
3179        switch (encoding)
3180        {
3181            case eEncodingT1:
3182                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3183                n = Bits32 (opcode, 10, 8);
3184                registers = Bits32 (opcode, 7, 0);
3185                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3186                wback = BitIsClear (registers, n);
3187                // if BitCount(registers) < 1 then UNPREDICTABLE;
3188                if (BitCount(registers) < 1)
3189                    return false;
3190                break;
3191            case eEncodingT2:
3192                // if W == '1' && Rn == '1101' then SEE POP;
3193                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3194                n = Bits32 (opcode, 19, 16);
3195                registers = Bits32 (opcode, 15, 0);
3196                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3197                wback = BitIsSet (opcode, 21);
3198
3199                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3200                if ((n == 15)
3201                    || (BitCount (registers) < 2)
3202                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3203                    return false;
3204
3205                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3206                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3207                    return false;
3208
3209                // if wback && registers<n> == '1' then UNPREDICTABLE;
3210                if (wback
3211                    && BitIsSet (registers, n))
3212                    return false;
3213                break;
3214
3215            case eEncodingA1:
3216                n = Bits32 (opcode, 19, 16);
3217                registers = Bits32 (opcode, 15, 0);
3218                wback = BitIsSet (opcode, 21);
3219                if ((n == 15)
3220                    || (BitCount (registers) < 1))
3221                    return false;
3222                break;
3223            default:
3224                return false;
3225        }
3226
3227        int32_t offset = 0;
3228        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3229        if (!success)
3230            return false;
3231
3232        EmulateInstruction::Context context;
3233        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3234        Register dwarf_reg;
3235        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3236        context.SetRegisterPlusOffset (dwarf_reg, offset);
3237
3238        for (int i = 0; i < 14; ++i)
3239        {
3240            if (BitIsSet (registers, i))
3241            {
3242                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3243                context.SetRegisterPlusOffset (dwarf_reg, offset);
3244                if (wback && (n == 13)) // Pop Instruction
3245                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
3246
3247                // R[i] = MemA [address, 4]; address = address + 4;
3248                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3249                if (!success)
3250                    return false;
3251
3252                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3253                    return false;
3254
3255                offset += addr_byte_size;
3256            }
3257        }
3258
3259        if (BitIsSet (registers, 15))
3260        {
3261            //LoadWritePC (MemA [address, 4]);
3262            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3263            context.SetRegisterPlusOffset (dwarf_reg, offset);
3264            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3265            if (!success)
3266                return false;
3267            // In ARMv5T and above, this is an interworking branch.
3268            if (!LoadWritePC(context, data))
3269                return false;
3270        }
3271
3272        if (wback && BitIsClear (registers, n))
3273        {
3274            // R[n] = R[n] + 4 * BitCount (registers)
3275            int32_t offset = addr_byte_size * BitCount (registers);
3276            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3277            context.SetRegisterPlusOffset (dwarf_reg, offset);
3278
3279            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3280                return false;
3281        }
3282        if (wback && BitIsSet (registers, n))
3283            // R[n] bits(32) UNKNOWN;
3284            return WriteBits32Unknown (n);
3285    }
3286    return true;
3287}
3288
3289// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3290// The consecutive memory locations end at this address and the address just below the lowest of those locations
3291// can optionally be written back to the base register.
3292bool
3293EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3294{
3295#if 0
3296    // ARM pseudo code...
3297    if ConditionPassed() then
3298        EncodingSpecificOperations();
3299        address = R[n] - 4*BitCount(registers) + 4;
3300
3301        for i = 0 to 14
3302            if registers<i> == '1' then
3303                  R[i] = MemA[address,4]; address = address + 4;
3304
3305        if registers<15> == '1' then
3306            LoadWritePC(MemA[address,4]);
3307
3308        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3309        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3310#endif
3311
3312    bool success = false;
3313
3314    if (ConditionPassed(opcode))
3315    {
3316        uint32_t n;
3317        uint32_t registers = 0;
3318        bool wback;
3319        const uint32_t addr_byte_size = GetAddressByteSize();
3320
3321        // EncodingSpecificOperations();
3322        switch (encoding)
3323        {
3324            case eEncodingA1:
3325                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3326                n = Bits32 (opcode, 19, 16);
3327                registers = Bits32 (opcode, 15, 0);
3328                wback = BitIsSet (opcode, 21);
3329
3330                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3331                if ((n == 15) || (BitCount (registers) < 1))
3332                    return false;
3333
3334                break;
3335
3336            default:
3337                return false;
3338        }
3339        // address = R[n] - 4*BitCount(registers) + 4;
3340
3341        int32_t offset = 0;
3342        addr_t Rn = ReadCoreReg (n, &success);
3343
3344        if (!success)
3345            return false;
3346
3347        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3348
3349        EmulateInstruction::Context context;
3350        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3351        Register dwarf_reg;
3352        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3353        context.SetRegisterPlusOffset (dwarf_reg, offset);
3354
3355        // for i = 0 to 14
3356        for (int i = 0; i < 14; ++i)
3357        {
3358            // if registers<i> == '1' then
3359            if (BitIsSet (registers, i))
3360            {
3361                  // R[i] = MemA[address,4]; address = address + 4;
3362                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3363                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3364                  if (!success)
3365                      return false;
3366                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3367                      return false;
3368                  offset += addr_byte_size;
3369            }
3370        }
3371
3372        // if registers<15> == '1' then
3373        //     LoadWritePC(MemA[address,4]);
3374        if (BitIsSet (registers, 15))
3375        {
3376            context.SetRegisterPlusOffset (dwarf_reg, offset);
3377            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3378            if (!success)
3379                return false;
3380            // In ARMv5T and above, this is an interworking branch.
3381            if (!LoadWritePC(context, data))
3382                return false;
3383        }
3384
3385        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3386        if (wback && BitIsClear (registers, n))
3387        {
3388            if (!success)
3389                return false;
3390
3391            offset = (addr_byte_size * BitCount (registers)) * -1;
3392            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3393            context.SetImmediateSigned (offset);
3394            addr_t addr = Rn + offset;
3395            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3396                return false;
3397        }
3398
3399        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3400        if (wback && BitIsSet (registers, n))
3401            return WriteBits32Unknown (n);
3402    }
3403    return true;
3404}
3405
3406// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3407// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3408// be optionally written back to the base register.
3409bool
3410EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3411{
3412#if 0
3413    // ARM pseudo code...
3414    if ConditionPassed() then
3415        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3416        address = R[n] - 4*BitCount(registers);
3417
3418        for i = 0 to 14
3419            if registers<i> == '1' then
3420                  R[i] = MemA[address,4]; address = address + 4;
3421        if registers<15> == '1' then
3422                  LoadWritePC(MemA[address,4]);
3423
3424        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3425        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3426#endif
3427
3428    bool success = false;
3429
3430    if (ConditionPassed(opcode))
3431    {
3432        uint32_t n;
3433        uint32_t registers = 0;
3434        bool wback;
3435        const uint32_t addr_byte_size = GetAddressByteSize();
3436        switch (encoding)
3437        {
3438            case eEncodingT1:
3439                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3440                n = Bits32 (opcode, 19, 16);
3441                registers = Bits32 (opcode, 15, 0);
3442                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3443                wback = BitIsSet (opcode, 21);
3444
3445                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3446                if ((n == 15)
3447                    || (BitCount (registers) < 2)
3448                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3449                    return false;
3450
3451                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3452                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3453                    return false;
3454
3455                // if wback && registers<n> == '1' then UNPREDICTABLE;
3456                if (wback && BitIsSet (registers, n))
3457                    return false;
3458
3459                break;
3460
3461            case eEncodingA1:
3462                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3463                n = Bits32 (opcode, 19, 16);
3464                registers = Bits32 (opcode, 15, 0);
3465                wback = BitIsSet (opcode, 21);
3466
3467                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3468                if ((n == 15) || (BitCount (registers) < 1))
3469                    return false;
3470
3471                break;
3472
3473            default:
3474                return false;
3475        }
3476
3477        // address = R[n] - 4*BitCount(registers);
3478
3479        int32_t offset = 0;
3480        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3481
3482        if (!success)
3483            return false;
3484
3485        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3486        EmulateInstruction::Context context;
3487        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3488        Register dwarf_reg;
3489        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3490        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3491
3492        for (int i = 0; i < 14; ++i)
3493        {
3494            if (BitIsSet (registers, i))
3495            {
3496                // R[i] = MemA[address,4]; address = address + 4;
3497                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3498                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3499                if (!success)
3500                    return false;
3501
3502                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3503                    return false;
3504
3505                offset += addr_byte_size;
3506            }
3507        }
3508
3509        // if registers<15> == '1' then
3510        //     LoadWritePC(MemA[address,4]);
3511        if (BitIsSet (registers, 15))
3512        {
3513            context.SetRegisterPlusOffset (dwarf_reg, offset);
3514            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3515            if (!success)
3516                return false;
3517            // In ARMv5T and above, this is an interworking branch.
3518            if (!LoadWritePC(context, data))
3519                return false;
3520        }
3521
3522        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3523        if (wback && BitIsClear (registers, n))
3524        {
3525            if (!success)
3526                return false;
3527
3528            offset = (addr_byte_size * BitCount (registers)) * -1;
3529            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3530            context.SetImmediateSigned (offset);
3531            addr_t addr = Rn + offset;
3532            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3533                return false;
3534        }
3535
3536        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3537        if (wback && BitIsSet (registers, n))
3538            return WriteBits32Unknown (n);
3539    }
3540    return true;
3541}
3542
3543// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3544// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3545// optinoally be written back to the base register.
3546bool
3547EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3548{
3549#if 0
3550    if ConditionPassed() then
3551        EncodingSpecificOperations();
3552        address = R[n] + 4;
3553
3554        for i = 0 to 14
3555            if registers<i> == '1' then
3556                  R[i] = MemA[address,4]; address = address + 4;
3557        if registers<15> == '1' then
3558            LoadWritePC(MemA[address,4]);
3559
3560        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3561        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3562#endif
3563
3564    bool success = false;
3565
3566    if (ConditionPassed(opcode))
3567    {
3568        uint32_t n;
3569        uint32_t registers = 0;
3570        bool wback;
3571        const uint32_t addr_byte_size = GetAddressByteSize();
3572        switch (encoding)
3573        {
3574            case eEncodingA1:
3575                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3576                n = Bits32 (opcode, 19, 16);
3577                registers = Bits32 (opcode, 15, 0);
3578                wback = BitIsSet (opcode, 21);
3579
3580                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3581                if ((n == 15) || (BitCount (registers) < 1))
3582                    return false;
3583
3584                break;
3585            default:
3586                return false;
3587        }
3588        // address = R[n] + 4;
3589
3590        int32_t offset = 0;
3591        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3592
3593        if (!success)
3594            return false;
3595
3596        addr_t address = Rn + addr_byte_size;
3597
3598        EmulateInstruction::Context context;
3599        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3600        Register dwarf_reg;
3601        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3602        context.SetRegisterPlusOffset (dwarf_reg, offset);
3603
3604        for (int i = 0; i < 14; ++i)
3605        {
3606            if (BitIsSet (registers, i))
3607            {
3608                // R[i] = MemA[address,4]; address = address + 4;
3609
3610                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3611                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3612                if (!success)
3613                    return false;
3614
3615                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3616                    return false;
3617
3618                offset += addr_byte_size;
3619            }
3620        }
3621
3622        // if registers<15> == '1' then
3623        //     LoadWritePC(MemA[address,4]);
3624        if (BitIsSet (registers, 15))
3625        {
3626            context.SetRegisterPlusOffset (dwarf_reg, offset);
3627            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3628            if (!success)
3629                return false;
3630            // In ARMv5T and above, this is an interworking branch.
3631            if (!LoadWritePC(context, data))
3632                return false;
3633        }
3634
3635        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3636        if (wback && BitIsClear (registers, n))
3637        {
3638            if (!success)
3639                return false;
3640
3641            offset = addr_byte_size * BitCount (registers);
3642            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3643            context.SetImmediateSigned (offset);
3644            addr_t addr = Rn + offset;
3645            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3646                return false;
3647        }
3648
3649        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3650        if (wback && BitIsSet (registers, n))
3651            return WriteBits32Unknown (n);
3652    }
3653    return true;
3654}
3655
3656// Load Register (immediate) calculates an address from a base register value and
3657// an immediate offset, loads a word from memory, and writes to a register.
3658// LDR (immediate, Thumb)
3659bool
3660EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3661{
3662#if 0
3663    // ARM pseudo code...
3664    if (ConditionPassed())
3665    {
3666        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3667        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3668        address = if index then offset_addr else R[n];
3669        data = MemU[address,4];
3670        if wback then R[n] = offset_addr;
3671        if t == 15 then
3672            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3673        elsif UnalignedSupport() || address<1:0> = '00' then
3674            R[t] = data;
3675        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3676    }
3677#endif
3678
3679    bool success = false;
3680
3681    if (ConditionPassed(opcode))
3682    {
3683        uint32_t Rt; // the destination register
3684        uint32_t Rn; // the base register
3685        uint32_t imm32; // the immediate offset used to form the address
3686        addr_t offset_addr; // the offset address
3687        addr_t address; // the calculated address
3688        uint32_t data; // the literal data value from memory load
3689        bool add, index, wback;
3690        switch (encoding) {
3691            case eEncodingT1:
3692                Rt = Bits32(opcode, 5, 3);
3693                Rn = Bits32(opcode, 2, 0);
3694                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3695                // index = TRUE; add = TRUE; wback = FALSE
3696                add = true;
3697                index = true;
3698                wback = false;
3699
3700                break;
3701
3702            case eEncodingT2:
3703                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3704                Rt = Bits32 (opcode, 10, 8);
3705                Rn = 13;
3706                imm32 = Bits32 (opcode, 7, 0) << 2;
3707
3708                // index = TRUE; add = TRUE; wback = FALSE;
3709                index = true;
3710                add = true;
3711                wback = false;
3712
3713                break;
3714
3715            case eEncodingT3:
3716                // if Rn == '1111' then SEE LDR (literal);
3717                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3718                Rt = Bits32 (opcode, 15, 12);
3719                Rn = Bits32 (opcode, 19, 16);
3720                imm32 = Bits32 (opcode, 11, 0);
3721
3722                // index = TRUE; add = TRUE; wback = FALSE;
3723                index = true;
3724                add = true;
3725                wback = false;
3726
3727                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3728                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3729                    return false;
3730
3731                break;
3732
3733            case eEncodingT4:
3734                // if Rn == '1111' then SEE LDR (literal);
3735                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3736                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3737                // if P == '0' && W == '0' then UNDEFINED;
3738                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3739                    return false;
3740
3741                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3742                Rt = Bits32 (opcode, 15, 12);
3743                Rn = Bits32 (opcode, 19, 16);
3744                imm32 = Bits32 (opcode, 7, 0);
3745
3746                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3747                index = BitIsSet (opcode, 10);
3748                add = BitIsSet (opcode, 9);
3749                wback = BitIsSet (opcode, 8);
3750
3751                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3752                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3753                    return false;
3754
3755                break;
3756
3757            default:
3758                return false;
3759        }
3760        uint32_t base = ReadCoreReg (Rn, &success);
3761        if (!success)
3762            return false;
3763        if (add)
3764            offset_addr = base + imm32;
3765        else
3766            offset_addr = base - imm32;
3767
3768        address = (index ? offset_addr : base);
3769
3770        Register base_reg;
3771        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
3772        if (wback)
3773        {
3774            EmulateInstruction::Context ctx;
3775            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3776            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3777
3778            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3779                return false;
3780        }
3781
3782        // Prepare to write to the Rt register.
3783        EmulateInstruction::Context context;
3784        context.type = EmulateInstruction::eContextRegisterLoad;
3785        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3786
3787        // Read memory from the address.
3788        data = MemURead(context, address, 4, 0, &success);
3789        if (!success)
3790            return false;
3791
3792        if (Rt == 15)
3793        {
3794            if (Bits32(address, 1, 0) == 0)
3795            {
3796                if (!LoadWritePC(context, data))
3797                    return false;
3798            }
3799            else
3800                return false;
3801        }
3802        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3803        {
3804            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3805                return false;
3806        }
3807        else
3808            WriteBits32Unknown (Rt);
3809    }
3810    return true;
3811}
3812
3813// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3814// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3815// of those locations can optionally be written back to the base register.
3816bool
3817EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3818{
3819#if 0
3820    if ConditionPassed() then
3821        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3822        address = R[n];
3823
3824        for i = 0 to 14
3825            if registers<i> == '1' then
3826                if i == n && wback && i != LowestSetBit(registers) then
3827                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3828                else
3829                    MemA[address,4] = R[i];
3830                address = address + 4;
3831
3832        if registers<15> == '1' then // Only possible for encoding A1
3833            MemA[address,4] = PCStoreValue();
3834        if wback then R[n] = R[n] + 4*BitCount(registers);
3835#endif
3836
3837    bool success = false;
3838
3839    if (ConditionPassed(opcode))
3840    {
3841        uint32_t n;
3842        uint32_t registers = 0;
3843        bool wback;
3844        const uint32_t addr_byte_size = GetAddressByteSize();
3845
3846        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3847        switch (encoding)
3848        {
3849            case eEncodingT1:
3850                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
3851                n = Bits32 (opcode, 10, 8);
3852                registers = Bits32 (opcode, 7, 0);
3853                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3854                wback = true;
3855
3856                // if BitCount(registers) < 1 then UNPREDICTABLE;
3857                if (BitCount (registers) < 1)
3858                    return false;
3859
3860                break;
3861
3862            case eEncodingT2:
3863                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
3864                n = Bits32 (opcode, 19, 16);
3865                registers = Bits32 (opcode, 15, 0);
3866                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3867                wback = BitIsSet (opcode, 21);
3868
3869                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3870                if ((n == 15) || (BitCount (registers) < 2))
3871                    return false;
3872
3873                // if wback && registers<n> == '1' then UNPREDICTABLE;
3874                if (wback && BitIsSet (registers, n))
3875                    return false;
3876
3877                break;
3878
3879            case eEncodingA1:
3880                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3881                n = Bits32 (opcode, 19, 16);
3882                registers = Bits32 (opcode, 15, 0);
3883                wback = BitIsSet (opcode, 21);
3884
3885                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3886                if ((n == 15) || (BitCount (registers) < 1))
3887                    return false;
3888
3889                break;
3890
3891            default:
3892                return false;
3893        }
3894
3895        // address = R[n];
3896        int32_t offset = 0;
3897        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3898        if (!success)
3899            return false;
3900
3901        EmulateInstruction::Context context;
3902        context.type = EmulateInstruction::eContextRegisterStore;
3903        Register base_reg;
3904        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3905
3906        // for i = 0 to 14
3907        int lowest_set_bit = 14;
3908        for (int i = 0; i < 14; ++i)
3909        {
3910            // if registers<i> == '1' then
3911            if (BitIsSet (registers, i))
3912            {
3913                  if (i < lowest_set_bit)
3914                      lowest_set_bit = i;
3915                  // if i == n && wback && i != LowestSetBit(registers) then
3916                  if ((i == n) && wback && (i != lowest_set_bit))
3917                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3918                      WriteBits32UnknownToMemory (address + offset);
3919                  else
3920                  {
3921                     // MemA[address,4] = R[i];
3922                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3923                      if (!success)
3924                          return false;
3925
3926                      Register data_reg;
3927                      data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3928                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3929                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
3930                          return false;
3931                  }
3932
3933                  // address = address + 4;
3934                  offset += addr_byte_size;
3935            }
3936        }
3937
3938        // if registers<15> == '1' then // Only possible for encoding A1
3939        //     MemA[address,4] = PCStoreValue();
3940        if (BitIsSet (registers, 15))
3941        {
3942            Register pc_reg;
3943            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3944            context.SetRegisterPlusOffset (pc_reg, 8);
3945            const uint32_t pc = ReadCoreReg (PC_REG, &success);
3946            if (!success)
3947                return false;
3948
3949            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
3950                return false;
3951        }
3952
3953        // if wback then R[n] = R[n] + 4*BitCount(registers);
3954        if (wback)
3955        {
3956            offset = addr_byte_size * BitCount (registers);
3957            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3958            context.SetImmediateSigned (offset);
3959            addr_t data = address + offset;
3960            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3961                return false;
3962        }
3963    }
3964    return true;
3965}
3966
3967// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
3968// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
3969// of those locations can optionally be written back to the base register.
3970bool
3971EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
3972{
3973#if 0
3974    if ConditionPassed() then
3975        EncodingSpecificOperations();
3976        address = R[n] - 4*BitCount(registers) + 4;
3977
3978        for i = 0 to 14
3979            if registers<i> == '1' then
3980                if i == n && wback && i != LowestSetBit(registers) then
3981                    MemA[address,4] = bits(32) UNKNOWN;
3982                else
3983                    MemA[address,4] = R[i];
3984                address = address + 4;
3985
3986        if registers<15> == '1' then
3987            MemA[address,4] = PCStoreValue();
3988
3989        if wback then R[n] = R[n] - 4*BitCount(registers);
3990#endif
3991
3992    bool success = false;
3993
3994    if (ConditionPassed(opcode))
3995    {
3996        uint32_t n;
3997        uint32_t registers = 0;
3998        bool wback;
3999        const uint32_t addr_byte_size = GetAddressByteSize();
4000
4001        // EncodingSpecificOperations();
4002        switch (encoding)
4003        {
4004            case eEncodingA1:
4005                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4006                n = Bits32 (opcode, 19, 16);
4007                registers = Bits32 (opcode, 15, 0);
4008                wback = BitIsSet (opcode, 21);
4009
4010                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4011                if ((n == 15) || (BitCount (registers) < 1))
4012                    return false;
4013                break;
4014            default:
4015                return false;
4016        }
4017
4018        // address = R[n] - 4*BitCount(registers) + 4;
4019        int32_t offset = 0;
4020        addr_t Rn = ReadCoreReg (n, &success);
4021        if (!success)
4022            return false;
4023
4024        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4025
4026        EmulateInstruction::Context context;
4027        context.type = EmulateInstruction::eContextRegisterStore;
4028        Register base_reg;
4029        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4030
4031        // for i = 0 to 14
4032        int lowest_bit_set = 14;
4033        for (int i = 0; i < 14; ++i)
4034        {
4035            // if registers<i> == '1' then
4036            if (BitIsSet (registers, i))
4037            {
4038                if (i < lowest_bit_set)
4039                    lowest_bit_set = i;
4040                //if i == n && wback && i != LowestSetBit(registers) then
4041                if ((i == n) && wback && (i != lowest_bit_set))
4042                    // MemA[address,4] = bits(32) UNKNOWN;
4043                    WriteBits32UnknownToMemory (address + offset);
4044                else
4045                {
4046                    // MemA[address,4] = R[i];
4047                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4048                    if (!success)
4049                        return false;
4050
4051                    Register data_reg;
4052                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4053                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4054                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4055                        return false;
4056                }
4057
4058                // address = address + 4;
4059                offset += addr_byte_size;
4060            }
4061        }
4062
4063        // if registers<15> == '1' then
4064        //    MemA[address,4] = PCStoreValue();
4065        if (BitIsSet (registers, 15))
4066        {
4067            Register pc_reg;
4068            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4069            context.SetRegisterPlusOffset (pc_reg, 8);
4070            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4071            if (!success)
4072                return false;
4073
4074            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4075                return false;
4076        }
4077
4078        // if wback then R[n] = R[n] - 4*BitCount(registers);
4079        if (wback)
4080        {
4081            offset = (addr_byte_size * BitCount (registers)) * -1;
4082            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4083            context.SetImmediateSigned (offset);
4084            addr_t data = Rn + offset;
4085            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4086                return false;
4087        }
4088    }
4089    return true;
4090}
4091
4092// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4093// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4094// those locations can optionally be written back to the base register.
4095bool
4096EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4097{
4098#if 0
4099    if ConditionPassed() then
4100        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4101        address = R[n] - 4*BitCount(registers);
4102
4103        for i = 0 to 14
4104            if registers<i> == '1' then
4105                if i == n && wback && i != LowestSetBit(registers) then
4106                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4107                else
4108                    MemA[address,4] = R[i];
4109                address = address + 4;
4110
4111        if registers<15> == '1' then // Only possible for encoding A1
4112            MemA[address,4] = PCStoreValue();
4113
4114        if wback then R[n] = R[n] - 4*BitCount(registers);
4115#endif
4116
4117
4118    bool success = false;
4119
4120    if (ConditionPassed(opcode))
4121    {
4122        uint32_t n;
4123        uint32_t registers = 0;
4124        bool wback;
4125        const uint32_t addr_byte_size = GetAddressByteSize();
4126
4127        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4128        switch (encoding)
4129        {
4130            case eEncodingT1:
4131                // if W == '1' && Rn == '1101' then SEE PUSH;
4132                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4133                {
4134                    // See PUSH
4135                }
4136                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4137                n = Bits32 (opcode, 19, 16);
4138                registers = Bits32 (opcode, 15, 0);
4139                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4140                wback = BitIsSet (opcode, 21);
4141                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4142                if ((n == 15) || BitCount (registers) < 2)
4143                    return false;
4144                // if wback && registers<n> == '1' then UNPREDICTABLE;
4145                if (wback && BitIsSet (registers, n))
4146                    return false;
4147                break;
4148
4149            case eEncodingA1:
4150                // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH;
4151                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4152                {
4153                    // See Push
4154                }
4155                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4156                n = Bits32 (opcode, 19, 16);
4157                registers = Bits32 (opcode, 15, 0);
4158                wback = BitIsSet (opcode, 21);
4159                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4160                if ((n == 15) || BitCount (registers) < 1)
4161                    return false;
4162                break;
4163
4164            default:
4165                return false;
4166        }
4167
4168        // address = R[n] - 4*BitCount(registers);
4169
4170        int32_t offset = 0;
4171        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4172        if (!success)
4173        return false;
4174
4175        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4176
4177        EmulateInstruction::Context context;
4178        context.type = EmulateInstruction::eContextRegisterStore;
4179        Register base_reg;
4180        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4181
4182        // for i = 0 to 14
4183        uint32_t lowest_set_bit = 14;
4184        for (int i = 0; i < 14; ++i)
4185        {
4186            // if registers<i> == '1' then
4187            if (BitIsSet (registers, i))
4188            {
4189                if (i < lowest_set_bit)
4190                    lowest_set_bit = i;
4191                // if i == n && wback && i != LowestSetBit(registers) then
4192                if ((i == n) && wback && (i != lowest_set_bit))
4193                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4194                    WriteBits32UnknownToMemory (address + offset);
4195                else
4196                {
4197                    // MemA[address,4] = R[i];
4198                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4199                    if (!success)
4200                        return false;
4201
4202                    Register data_reg;
4203                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4204                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4205                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4206                        return false;
4207                }
4208
4209                // address = address + 4;
4210                offset += addr_byte_size;
4211            }
4212        }
4213
4214        // if registers<15> == '1' then // Only possible for encoding A1
4215        //     MemA[address,4] = PCStoreValue();
4216        if (BitIsSet (registers, 15))
4217        {
4218            Register pc_reg;
4219            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4220            context.SetRegisterPlusOffset (pc_reg, 8);
4221            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4222            if (!success)
4223                return false;
4224
4225            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4226                return false;
4227        }
4228
4229        // if wback then R[n] = R[n] - 4*BitCount(registers);
4230        if (wback)
4231        {
4232            offset = (addr_byte_size * BitCount (registers)) * -1;
4233            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4234            context.SetImmediateSigned (offset);
4235            addr_t data = Rn + offset;
4236            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4237                return false;
4238        }
4239    }
4240    return true;
4241}
4242
4243// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4244// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4245// of those locations can optionally be written back to the base register.
4246bool
4247EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4248{
4249#if 0
4250    if ConditionPassed() then
4251        EncodingSpecificOperations();
4252        address = R[n] + 4;
4253
4254        for i = 0 to 14
4255            if registers<i> == '1' then
4256                if i == n && wback && i != LowestSetBit(registers) then
4257                    MemA[address,4] = bits(32) UNKNOWN;
4258                else
4259                    MemA[address,4] = R[i];
4260                address = address + 4;
4261
4262        if registers<15> == '1' then
4263            MemA[address,4] = PCStoreValue();
4264
4265        if wback then R[n] = R[n] + 4*BitCount(registers);
4266#endif
4267
4268    bool success = false;
4269
4270    if (ConditionPassed(opcode))
4271    {
4272        uint32_t n;
4273        uint32_t registers = 0;
4274        bool wback;
4275        const uint32_t addr_byte_size = GetAddressByteSize();
4276
4277        // EncodingSpecificOperations();
4278        switch (encoding)
4279        {
4280            case eEncodingA1:
4281                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4282                n = Bits32 (opcode, 19, 16);
4283                registers = Bits32 (opcode, 15, 0);
4284                wback = BitIsSet (opcode, 21);
4285
4286                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4287                if ((n == 15) && (BitCount (registers) < 1))
4288                    return false;
4289                break;
4290            default:
4291                return false;
4292        }
4293        // address = R[n] + 4;
4294
4295        int32_t offset = 0;
4296        addr_t Rn = ReadCoreReg (n, &success);
4297        if (!success)
4298            return false;
4299
4300        addr_t address = Rn + addr_byte_size;
4301
4302        EmulateInstruction::Context context;
4303        context.type = EmulateInstruction::eContextRegisterStore;
4304        Register base_reg;
4305        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4306
4307        uint32_t lowest_set_bit = 14;
4308        // for i = 0 to 14
4309        for (int i = 0; i < 14; ++i)
4310        {
4311            // if registers<i> == '1' then
4312            if (BitIsSet (registers, i))
4313            {
4314                if (i < lowest_set_bit)
4315                    lowest_set_bit = i;
4316                // if i == n && wback && i != LowestSetBit(registers) then
4317                if ((i == n) && wback && (i != lowest_set_bit))
4318                    // MemA[address,4] = bits(32) UNKNOWN;
4319                    WriteBits32UnknownToMemory (address + offset);
4320                // else
4321                else
4322                {
4323                    // MemA[address,4] = R[i];
4324                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4325                    if (!success)
4326                        return false;
4327
4328                    Register data_reg;
4329                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4330                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4331                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4332                        return false;
4333                }
4334
4335                // address = address + 4;
4336                offset += addr_byte_size;
4337            }
4338        }
4339
4340        // if registers<15> == '1' then
4341            // MemA[address,4] = PCStoreValue();
4342        if (BitIsSet (registers, 15))
4343        {
4344            Register pc_reg;
4345            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4346            context.SetRegisterPlusOffset (pc_reg, 8);
4347            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4348            if (!success)
4349            return false;
4350
4351            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4352                return false;
4353        }
4354
4355        // if wback then R[n] = R[n] + 4*BitCount(registers);
4356        if (wback)
4357        {
4358            offset = addr_byte_size * BitCount (registers);
4359            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4360            context.SetImmediateSigned (offset);
4361            addr_t data = Rn + offset;
4362            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4363                return false;
4364        }
4365    }
4366    return true;
4367}
4368
4369// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4370// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4371bool
4372EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4373{
4374#if 0
4375    if ConditionPassed() then
4376        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4377        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4378        address = if index then offset_addr else R[n];
4379        if UnalignedSupport() || address<1:0> == '00' then
4380            MemU[address,4] = R[t];
4381        else // Can only occur before ARMv7
4382            MemU[address,4] = bits(32) UNKNOWN;
4383        if wback then R[n] = offset_addr;
4384#endif
4385
4386    bool success = false;
4387
4388    if (ConditionPassed(opcode))
4389    {
4390        const uint32_t addr_byte_size = GetAddressByteSize();
4391
4392        uint32_t t;
4393        uint32_t n;
4394        uint32_t imm32;
4395        bool index;
4396        bool add;
4397        bool wback;
4398        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4399        switch (encoding)
4400        {
4401            case eEncodingT1:
4402                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4403                t = Bits32 (opcode, 2, 0);
4404                n = Bits32 (opcode, 5, 3);
4405                imm32 = Bits32 (opcode, 10, 6) << 2;
4406
4407                // index = TRUE; add = TRUE; wback = FALSE;
4408                index = true;
4409                add = false;
4410                wback = false;
4411                break;
4412
4413            case eEncodingT2:
4414                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4415                t = Bits32 (opcode, 10, 8);
4416                n = 13;
4417                imm32 = Bits32 (opcode, 7, 0) << 2;
4418
4419                // index = TRUE; add = TRUE; wback = FALSE;
4420                index = true;
4421                add = true;
4422                wback = false;
4423                break;
4424
4425            case eEncodingT3:
4426                // if Rn == '1111' then UNDEFINED;
4427                if (Bits32 (opcode, 19, 16) == 15)
4428                    return false;
4429
4430                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4431                t = Bits32 (opcode, 15, 12);
4432                n = Bits32 (opcode, 19, 16);
4433                imm32 = Bits32 (opcode, 11, 0);
4434
4435                // index = TRUE; add = TRUE; wback = FALSE;
4436                index = true;
4437                add = true;
4438                wback = false;
4439
4440                // if t == 15 then UNPREDICTABLE;
4441                if (t == 15)
4442                    return false;
4443                break;
4444
4445            case eEncodingT4:
4446                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4447                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4448                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4449                if ((Bits32 (opcode, 19, 16) == 15)
4450                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4451                    return false;
4452
4453                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4454                t = Bits32 (opcode, 15, 12);
4455                n = Bits32 (opcode, 19, 16);
4456                imm32 = Bits32 (opcode, 7, 0);
4457
4458                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4459                index = BitIsSet (opcode, 10);
4460                add = BitIsSet (opcode, 9);
4461                wback = BitIsSet (opcode, 8);
4462
4463                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4464                if ((t == 15) || (wback && (n == t)))
4465                    return false;
4466                break;
4467
4468            default:
4469                return false;
4470        }
4471
4472        addr_t offset_addr;
4473        addr_t address;
4474
4475        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4476        uint32_t base_address = ReadCoreReg (n, &success);
4477        if (!success)
4478            return false;
4479
4480        if (add)
4481            offset_addr = base_address + imm32;
4482        else
4483            offset_addr = base_address - imm32;
4484
4485        // address = if index then offset_addr else R[n];
4486        if (index)
4487            address = offset_addr;
4488        else
4489            address = base_address;
4490
4491        EmulateInstruction::Context context;
4492        context.type = eContextRegisterStore;
4493        Register base_reg;
4494        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4495
4496        // if UnalignedSupport() || address<1:0> == '00' then
4497        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4498        {
4499            // MemU[address,4] = R[t];
4500            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4501            if (!success)
4502                return false;
4503
4504            Register data_reg;
4505            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4506            int32_t offset = address - base_address;
4507            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4508            if (!MemUWrite (context, address, data, addr_byte_size))
4509                return false;
4510        }
4511        else
4512        {
4513            // MemU[address,4] = bits(32) UNKNOWN;
4514            WriteBits32UnknownToMemory (address);
4515        }
4516
4517        // if wback then R[n] = offset_addr;
4518        if (wback)
4519        {
4520            context.type = eContextRegisterLoad;
4521            context.SetAddress (offset_addr);
4522            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4523                return false;
4524        }
4525    }
4526    return true;
4527}
4528
4529// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4530// word from a register to memory.   The offset register value can optionally be shifted.
4531bool
4532EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4533{
4534#if 0
4535    if ConditionPassed() then
4536        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4537        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4538        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4539        address = if index then offset_addr else R[n];
4540        if t == 15 then // Only possible for encoding A1
4541            data = PCStoreValue();
4542        else
4543            data = R[t];
4544        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4545            MemU[address,4] = data;
4546        else // Can only occur before ARMv7
4547            MemU[address,4] = bits(32) UNKNOWN;
4548        if wback then R[n] = offset_addr;
4549#endif
4550
4551    bool success = false;
4552
4553    if (ConditionPassed(opcode))
4554    {
4555        const uint32_t addr_byte_size = GetAddressByteSize();
4556
4557        uint32_t t;
4558        uint32_t n;
4559        uint32_t m;
4560        ARM_ShifterType shift_t;
4561        uint32_t shift_n;
4562        bool index;
4563        bool add;
4564        bool wback;
4565
4566        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4567        switch (encoding)
4568        {
4569            case eEncodingT1:
4570                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4571                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4572                t = Bits32 (opcode, 2, 0);
4573                n = Bits32 (opcode, 5, 3);
4574                m = Bits32 (opcode, 8, 6);
4575
4576                // index = TRUE; add = TRUE; wback = FALSE;
4577                index = true;
4578                add = true;
4579                wback = false;
4580
4581                // (shift_t, shift_n) = (SRType_LSL, 0);
4582                shift_t = SRType_LSL;
4583                shift_n = 0;
4584                break;
4585
4586            case eEncodingT2:
4587                // if Rn == '1111' then UNDEFINED;
4588                if (Bits32 (opcode, 19, 16) == 15)
4589                    return false;
4590
4591                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4592                t = Bits32 (opcode, 15, 12);
4593                n = Bits32 (opcode, 19, 16);
4594                m = Bits32 (opcode, 3, 0);
4595
4596                // index = TRUE; add = TRUE; wback = FALSE;
4597                index = true;
4598                add = true;
4599                wback = false;
4600
4601                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4602                shift_t = SRType_LSL;
4603                shift_n = Bits32 (opcode, 5, 4);
4604
4605                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4606                if ((t == 15) || (BadReg (m)))
4607                    return false;
4608                break;
4609
4610            case eEncodingA1:
4611            {
4612                // if P == '0' && W == '1' then SEE STRT;
4613                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4614                t = Bits32 (opcode, 15, 12);
4615                n = Bits32 (opcode, 19, 16);
4616                m = Bits32 (opcode, 3, 0);
4617
4618                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4619                index = BitIsSet (opcode, 24);
4620                add = BitIsSet (opcode, 23);
4621                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4622
4623                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4624                uint32_t typ = Bits32 (opcode, 6, 5);
4625                uint32_t imm5 = Bits32 (opcode, 11, 7);
4626                shift_n = DecodeImmShift(typ, imm5, shift_t);
4627
4628                // if m == 15 then UNPREDICTABLE;
4629                if (m == 15)
4630                    return false;
4631
4632                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4633                if (wback && ((n == 15) || (n == t)))
4634                    return false;
4635
4636                break;
4637            }
4638            default:
4639                return false;
4640        }
4641
4642        addr_t offset_addr;
4643        addr_t address;
4644        int32_t offset = 0;
4645
4646        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4647        if (!success)
4648            return false;
4649
4650        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4651        if (!success)
4652            return false;
4653
4654        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4655        offset = Shift (Rm_data, shift_t, shift_n, APSR_C);
4656
4657        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4658        if (add)
4659            offset_addr = base_address + offset;
4660        else
4661            offset_addr = base_address - offset;
4662
4663        // address = if index then offset_addr else R[n];
4664        if (index)
4665            address = offset_addr;
4666        else
4667            address = base_address;
4668
4669        uint32_t data;
4670        // if t == 15 then // Only possible for encoding A1
4671        if (t == 15)
4672            // data = PCStoreValue();
4673            data = ReadCoreReg (PC_REG, &success);
4674        else
4675            // data = R[t];
4676            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4677
4678        if (!success)
4679            return false;
4680
4681        EmulateInstruction::Context context;
4682        context.type = eContextRegisterStore;
4683
4684        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4685        if (UnalignedSupport ()
4686            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4687            || CurrentInstrSet() == eModeARM)
4688        {
4689            // MemU[address,4] = data;
4690
4691            Register base_reg;
4692            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4693
4694            Register data_reg;
4695            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4696
4697            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4698            if (!MemUWrite (context, address, data, addr_byte_size))
4699                return false;
4700
4701        }
4702        else
4703            // MemU[address,4] = bits(32) UNKNOWN;
4704            WriteBits32UnknownToMemory (address);
4705
4706        // if wback then R[n] = offset_addr;
4707        if (wback)
4708        {
4709            context.type = eContextRegisterLoad;
4710            context.SetAddress (offset_addr);
4711            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4712                return false;
4713        }
4714
4715    }
4716    return true;
4717}
4718
4719bool
4720EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4721{
4722#if 0
4723    if ConditionPassed() then
4724        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4725        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4726        address = if index then offset_addr else R[n];
4727        MemU[address,1] = R[t]<7:0>;
4728        if wback then R[n] = offset_addr;
4729#endif
4730
4731
4732    bool success = false;
4733
4734    if (ConditionPassed(opcode))
4735    {
4736        uint32_t t;
4737        uint32_t n;
4738        uint32_t imm32;
4739        bool index;
4740        bool add;
4741        bool wback;
4742        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4743        switch (encoding)
4744        {
4745            case eEncodingT1:
4746                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4747                t = Bits32 (opcode, 2, 0);
4748                n = Bits32 (opcode, 5, 3);
4749                imm32 = Bits32 (opcode, 10, 6);
4750
4751                // index = TRUE; add = TRUE; wback = FALSE;
4752                index = true;
4753                add = true;
4754                wback = false;
4755                break;
4756
4757            case eEncodingT2:
4758                // if Rn == '1111' then UNDEFINED;
4759                if (Bits32 (opcode, 19, 16) == 15)
4760                    return false;
4761
4762                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4763                t = Bits32 (opcode, 15, 12);
4764                n = Bits32 (opcode, 19, 16);
4765                imm32 = Bits32 (opcode, 11, 0);
4766
4767                // index = TRUE; add = TRUE; wback = FALSE;
4768                index = true;
4769                add = true;
4770                wback = false;
4771
4772                // if BadReg(t) then UNPREDICTABLE;
4773                if (BadReg (t))
4774                    return false;
4775                break;
4776
4777            case eEncodingT3:
4778                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4779                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4780                if (Bits32 (opcode, 19, 16) == 15)
4781                    return false;
4782
4783                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4784                t = Bits32 (opcode, 15, 12);
4785                n = Bits32 (opcode, 19, 16);
4786                imm32 = Bits32 (opcode, 7, 0);
4787
4788                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4789                index = BitIsSet (opcode, 10);
4790                add = BitIsSet (opcode, 9);
4791                wback = BitIsSet (opcode, 8);
4792
4793                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4794                if ((BadReg (t)) || (wback && (n == t)))
4795                    return false;
4796                break;
4797
4798            default:
4799                return false;
4800        }
4801
4802        addr_t offset_addr;
4803        addr_t address;
4804        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4805        if (!success)
4806            return false;
4807
4808        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4809        if (add)
4810            offset_addr = base_address + imm32;
4811        else
4812            offset_addr = base_address - imm32;
4813
4814        // address = if index then offset_addr else R[n];
4815        if (index)
4816            address = offset_addr;
4817        else
4818            address = base_address;
4819
4820        // MemU[address,1] = R[t]<7:0>
4821        Register base_reg;
4822        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4823
4824        Register data_reg;
4825        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4826
4827        EmulateInstruction::Context context;
4828        context.type = eContextRegisterStore;
4829        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4830
4831        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4832        if (!success)
4833            return false;
4834
4835        data = Bits32 (data, 7, 0);
4836
4837        if (!MemUWrite (context, address, data, 1))
4838            return false;
4839
4840        // if wback then R[n] = offset_addr;
4841        if (wback)
4842        {
4843            context.type = eContextRegisterLoad;
4844            context.SetAddress (offset_addr);
4845            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4846                return false;
4847        }
4848
4849    }
4850
4851    return true;
4852}
4853
4854// STRH (register) calculates an address from a base register value and an offset register value, and stores a
4855// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
4856bool
4857EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
4858{
4859#if 0
4860    if ConditionPassed() then
4861        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4862        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4863        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4864        address = if index then offset_addr else R[n];
4865        if UnalignedSupport() || address<0> == '0' then
4866            MemU[address,2] = R[t]<15:0>;
4867        else // Can only occur before ARMv7
4868            MemU[address,2] = bits(16) UNKNOWN;
4869        if wback then R[n] = offset_addr;
4870#endif
4871
4872    bool success = false;
4873
4874    if (ConditionPassed(opcode))
4875    {
4876        uint32_t t;
4877        uint32_t n;
4878        uint32_t m;
4879        bool index;
4880        bool add;
4881        bool wback;
4882        ARM_ShifterType shift_t;
4883        uint32_t shift_n;
4884
4885        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4886        switch (encoding)
4887        {
4888            case eEncodingT1:
4889                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4890                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4891                t = Bits32 (opcode, 2, 0);
4892                n = Bits32 (opcode, 5, 3);
4893                m = Bits32 (opcode, 8, 6);
4894
4895                // index = TRUE; add = TRUE; wback = FALSE;
4896                index = true;
4897                add = true;
4898                wback = false;
4899
4900                // (shift_t, shift_n) = (SRType_LSL, 0);
4901                shift_t = SRType_LSL;
4902                shift_n = 0;
4903
4904                break;
4905
4906            case eEncodingT2:
4907                // if Rn == '1111' then UNDEFINED;
4908                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4909                t = Bits32 (opcode, 15, 12);
4910                n = Bits32 (opcode, 19, 16);
4911                m = Bits32 (opcode, 3, 0);
4912                if (n == 15)
4913                    return false;
4914
4915                // index = TRUE; add = TRUE; wback = FALSE;
4916                index = true;
4917                add = true;
4918                wback = false;
4919
4920                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4921                shift_t = SRType_LSL;
4922                shift_n = Bits32 (opcode, 5, 4);
4923
4924                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
4925                if (BadReg (t) || BadReg (m))
4926                    return false;
4927
4928                break;
4929
4930            case eEncodingA1:
4931                // if P == '0' && W == '1' then SEE STRHT;
4932                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4933                t = Bits32 (opcode, 15, 12);
4934                n = Bits32 (opcode, 19, 16);
4935                m = Bits32 (opcode, 3, 0);
4936
4937                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4938                index = BitIsSet (opcode, 24);
4939                add = BitIsSet (opcode, 23);
4940                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4941
4942                // (shift_t, shift_n) = (SRType_LSL, 0);
4943                shift_t = SRType_LSL;
4944                shift_n = 0;
4945
4946                // if t == 15 || m == 15 then UNPREDICTABLE;
4947                if ((t == 15) || (m == 15))
4948                    return false;
4949
4950                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4951                if (wback && ((n == 15) || (n == t)))
4952                    return false;
4953
4954                break;
4955
4956            default:
4957                return false;
4958        }
4959
4960        uint32_t Rm = ReadCoreReg (m, &success);
4961        if (!success)
4962            return false;
4963
4964        uint32_t Rn = ReadCoreReg (n, &success);
4965        if (!success)
4966            return false;
4967
4968        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4969        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
4970
4971        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4972        addr_t offset_addr;
4973        if (add)
4974            offset_addr = Rn + offset;
4975        else
4976            offset_addr = Rn - offset;
4977
4978        // address = if index then offset_addr else R[n];
4979        addr_t address;
4980        if (index)
4981            address = offset_addr;
4982        else
4983            address = Rn;
4984
4985        EmulateInstruction::Context context;
4986        context.type = eContextRegisterStore;
4987        Register base_reg;
4988        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4989        Register offset_reg;
4990        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
4991
4992        // if UnalignedSupport() || address<0> == '0' then
4993        if (UnalignedSupport() || BitIsClear (address, 0))
4994        {
4995            // MemU[address,2] = R[t]<15:0>;
4996            uint32_t Rt = ReadCoreReg (t, &success);
4997            if (!success)
4998                return false;
4999
5000            EmulateInstruction::Context context;
5001            context.type = eContextRegisterStore;
5002            Register base_reg;
5003            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5004            Register offset_reg;
5005            offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5006            Register data_reg;
5007            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
5008            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5009
5010            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5011                return false;
5012        }
5013        else // Can only occur before ARMv7
5014        {
5015            // MemU[address,2] = bits(16) UNKNOWN;
5016        }
5017
5018        // if wback then R[n] = offset_addr;
5019        if (wback)
5020        {
5021            context.type = eContextAdjustBaseRegister;
5022            context.SetAddress (offset_addr);
5023            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5024                return false;
5025        }
5026    }
5027
5028    return true;
5029}
5030
5031// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5032// and writes the result to the destination register.  It can optionally update the condition flags
5033// based on the result.
5034bool
5035EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5036{
5037#if 0
5038    // ARM pseudo code...
5039    if ConditionPassed() then
5040        EncodingSpecificOperations();
5041        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5042        if d == 15 then         // Can only occur for ARM encoding
5043            ALUWritePC(result); // setflags is always FALSE here
5044        else
5045            R[d] = result;
5046            if setflags then
5047                APSR.N = result<31>;
5048                APSR.Z = IsZeroBit(result);
5049                APSR.C = carry;
5050                APSR.V = overflow;
5051#endif
5052
5053    bool success = false;
5054
5055    if (ConditionPassed(opcode))
5056    {
5057        uint32_t Rd, Rn;
5058        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5059        bool setflags;
5060        switch (encoding)
5061        {
5062        case eEncodingT1:
5063            Rd = Bits32(opcode, 11, 8);
5064            Rn = Bits32(opcode, 19, 16);
5065            setflags = BitIsSet(opcode, 20);
5066            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5067            if (BadReg(Rd) || BadReg(Rn))
5068                return false;
5069            break;
5070        case eEncodingA1:
5071            Rd = Bits32(opcode, 15, 12);
5072            Rn = Bits32(opcode, 19, 16);
5073            setflags = BitIsSet(opcode, 20);
5074            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5075            // TODO: Emulate SUBS PC, LR and related instructions.
5076            if (Rd == 15 && setflags)
5077                return false;
5078            break;
5079        default:
5080            return false;
5081        }
5082
5083        // Read the first operand.
5084        int32_t val1 = ReadCoreReg(Rn, &success);
5085        if (!success)
5086            return false;
5087
5088        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5089
5090        EmulateInstruction::Context context;
5091        context.type = EmulateInstruction::eContextImmediate;
5092        context.SetNoArgs ();
5093
5094        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5095            return false;
5096    }
5097    return true;
5098}
5099
5100// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5101// register value, and writes the result to the destination register.  It can optionally update the
5102// condition flags based on the result.
5103bool
5104EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5105{
5106#if 0
5107    // ARM pseudo code...
5108    if ConditionPassed() then
5109        EncodingSpecificOperations();
5110        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5111        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5112        if d == 15 then         // Can only occur for ARM encoding
5113            ALUWritePC(result); // setflags is always FALSE here
5114        else
5115            R[d] = result;
5116            if setflags then
5117                APSR.N = result<31>;
5118                APSR.Z = IsZeroBit(result);
5119                APSR.C = carry;
5120                APSR.V = overflow;
5121#endif
5122
5123    bool success = false;
5124
5125    if (ConditionPassed(opcode))
5126    {
5127        uint32_t Rd, Rn, Rm;
5128        ARM_ShifterType shift_t;
5129        uint32_t shift_n; // the shift applied to the value read from Rm
5130        bool setflags;
5131        switch (encoding)
5132        {
5133        case eEncodingT1:
5134            Rd = Rn = Bits32(opcode, 2, 0);
5135            Rm = Bits32(opcode, 5, 3);
5136            setflags = !InITBlock();
5137            shift_t = SRType_LSL;
5138            shift_n = 0;
5139            break;
5140        case eEncodingT2:
5141            Rd = Bits32(opcode, 11, 8);
5142            Rn = Bits32(opcode, 19, 16);
5143            Rm = Bits32(opcode, 3, 0);
5144            setflags = BitIsSet(opcode, 20);
5145            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5146            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5147                return false;
5148            break;
5149        case eEncodingA1:
5150            Rd = Bits32(opcode, 15, 12);
5151            Rn = Bits32(opcode, 19, 16);
5152            Rm = Bits32(opcode, 3, 0);
5153            setflags = BitIsSet(opcode, 20);
5154            shift_n = DecodeImmShiftARM(opcode, shift_t);
5155            // TODO: Emulate SUBS PC, LR and related instructions.
5156            if (Rd == 15 && setflags)
5157                return false;
5158            break;
5159        default:
5160            return false;
5161        }
5162
5163        // Read the first operand.
5164        int32_t val1 = ReadCoreReg(Rn, &success);
5165        if (!success)
5166            return false;
5167
5168        // Read the second operand.
5169        int32_t val2 = ReadCoreReg(Rm, &success);
5170        if (!success)
5171            return false;
5172
5173        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
5174        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5175
5176        EmulateInstruction::Context context;
5177        context.type = EmulateInstruction::eContextImmediate;
5178        context.SetNoArgs ();
5179
5180        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5181            return false;
5182    }
5183    return true;
5184}
5185
5186// This instruction adds an immediate value to the PC value to form a PC-relative address,
5187// and writes the result to the destination register.
5188bool
5189EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5190{
5191#if 0
5192    // ARM pseudo code...
5193    if ConditionPassed() then
5194        EncodingSpecificOperations();
5195        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5196        if d == 15 then         // Can only occur for ARM encodings
5197            ALUWritePC(result);
5198        else
5199            R[d] = result;
5200#endif
5201
5202    bool success = false;
5203
5204    if (ConditionPassed(opcode))
5205    {
5206        uint32_t Rd;
5207        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5208        bool add;
5209        switch (encoding)
5210        {
5211        case eEncodingT1:
5212            Rd = Bits32(opcode, 10, 8);
5213            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5214            break;
5215        case eEncodingT2:
5216        case eEncodingT3:
5217            Rd = Bits32(opcode, 11, 8);
5218            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5219            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5220            if (BadReg(Rd))
5221                return false;
5222            break;
5223        case eEncodingA1:
5224        case eEncodingA2:
5225            Rd = Bits32(opcode, 15, 12);
5226            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5227            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5228            break;
5229        default:
5230            return false;
5231        }
5232
5233        // Read the PC value.
5234        uint32_t pc = ReadCoreReg(PC_REG, &success);
5235        if (!success)
5236            return false;
5237
5238        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5239
5240        EmulateInstruction::Context context;
5241        context.type = EmulateInstruction::eContextImmediate;
5242        context.SetNoArgs ();
5243
5244        if (!WriteCoreReg(context, result, Rd))
5245            return false;
5246    }
5247    return true;
5248}
5249
5250// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5251// to the destination register.  It can optionally update the condition flags based on the result.
5252bool
5253EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5254{
5255#if 0
5256    // ARM pseudo code...
5257    if ConditionPassed() then
5258        EncodingSpecificOperations();
5259        result = R[n] AND imm32;
5260        if d == 15 then         // Can only occur for ARM encoding
5261            ALUWritePC(result); // setflags is always FALSE here
5262        else
5263            R[d] = result;
5264            if setflags then
5265                APSR.N = result<31>;
5266                APSR.Z = IsZeroBit(result);
5267                APSR.C = carry;
5268                // APSR.V unchanged
5269#endif
5270
5271    bool success = false;
5272
5273    if (ConditionPassed(opcode))
5274    {
5275        uint32_t Rd, Rn;
5276        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5277        bool setflags;
5278        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5279        switch (encoding)
5280        {
5281        case eEncodingT1:
5282            Rd = Bits32(opcode, 11, 8);
5283            Rn = Bits32(opcode, 19, 16);
5284            setflags = BitIsSet(opcode, 20);
5285            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5286            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5287            if (Rd == 15 && setflags)
5288                return EmulateTSTImm(opcode, eEncodingT1);
5289            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5290                return false;
5291            break;
5292        case eEncodingA1:
5293            Rd = Bits32(opcode, 15, 12);
5294            Rn = Bits32(opcode, 19, 16);
5295            setflags = BitIsSet(opcode, 20);
5296            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5297            // TODO: Emulate SUBS PC, LR and related instructions.
5298            if (Rd == 15 && setflags)
5299                return false;
5300            break;
5301        default:
5302            return false;
5303        }
5304
5305        // Read the first operand.
5306        uint32_t val1 = ReadCoreReg(Rn, &success);
5307        if (!success)
5308            return false;
5309
5310        uint32_t result = val1 & imm32;
5311
5312        EmulateInstruction::Context context;
5313        context.type = EmulateInstruction::eContextImmediate;
5314        context.SetNoArgs ();
5315
5316        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5317            return false;
5318    }
5319    return true;
5320}
5321
5322// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5323// and writes the result to the destination register.  It can optionally update the condition flags
5324// based on the result.
5325bool
5326EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5327{
5328#if 0
5329    // ARM pseudo code...
5330    if ConditionPassed() then
5331        EncodingSpecificOperations();
5332        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5333        result = R[n] AND shifted;
5334        if d == 15 then         // Can only occur for ARM encoding
5335            ALUWritePC(result); // setflags is always FALSE here
5336        else
5337            R[d] = result;
5338            if setflags then
5339                APSR.N = result<31>;
5340                APSR.Z = IsZeroBit(result);
5341                APSR.C = carry;
5342                // APSR.V unchanged
5343#endif
5344
5345    bool success = false;
5346
5347    if (ConditionPassed(opcode))
5348    {
5349        uint32_t Rd, Rn, Rm;
5350        ARM_ShifterType shift_t;
5351        uint32_t shift_n; // the shift applied to the value read from Rm
5352        bool setflags;
5353        uint32_t carry;
5354        switch (encoding)
5355        {
5356        case eEncodingT1:
5357            Rd = Rn = Bits32(opcode, 2, 0);
5358            Rm = Bits32(opcode, 5, 3);
5359            setflags = !InITBlock();
5360            shift_t = SRType_LSL;
5361            shift_n = 0;
5362            break;
5363        case eEncodingT2:
5364            Rd = Bits32(opcode, 11, 8);
5365            Rn = Bits32(opcode, 19, 16);
5366            Rm = Bits32(opcode, 3, 0);
5367            setflags = BitIsSet(opcode, 20);
5368            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5369            // if Rd == '1111' && S == '1' then SEE TST (register);
5370            if (Rd == 15 && setflags)
5371                return EmulateTSTReg(opcode, eEncodingT2);
5372            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5373                return false;
5374            break;
5375        case eEncodingA1:
5376            Rd = Bits32(opcode, 15, 12);
5377            Rn = Bits32(opcode, 19, 16);
5378            Rm = Bits32(opcode, 3, 0);
5379            setflags = BitIsSet(opcode, 20);
5380            shift_n = DecodeImmShiftARM(opcode, shift_t);
5381            // TODO: Emulate SUBS PC, LR and related instructions.
5382            if (Rd == 15 && setflags)
5383                return false;
5384            break;
5385        default:
5386            return false;
5387        }
5388
5389        // Read the first operand.
5390        uint32_t val1 = ReadCoreReg(Rn, &success);
5391        if (!success)
5392            return false;
5393
5394        // Read the second operand.
5395        uint32_t val2 = ReadCoreReg(Rm, &success);
5396        if (!success)
5397            return false;
5398
5399        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5400        uint32_t result = val1 & shifted;
5401
5402        EmulateInstruction::Context context;
5403        context.type = EmulateInstruction::eContextImmediate;
5404        context.SetNoArgs ();
5405
5406        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5407            return false;
5408    }
5409    return true;
5410}
5411
5412// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5413// immediate value, and writes the result to the destination register.  It can optionally update the
5414// condition flags based on the result.
5415bool
5416EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5417{
5418#if 0
5419    // ARM pseudo code...
5420    if ConditionPassed() then
5421        EncodingSpecificOperations();
5422        result = R[n] AND NOT(imm32);
5423        if d == 15 then         // Can only occur for ARM encoding
5424            ALUWritePC(result); // setflags is always FALSE here
5425        else
5426            R[d] = result;
5427            if setflags then
5428                APSR.N = result<31>;
5429                APSR.Z = IsZeroBit(result);
5430                APSR.C = carry;
5431                // APSR.V unchanged
5432#endif
5433
5434    bool success = false;
5435
5436    if (ConditionPassed(opcode))
5437    {
5438        uint32_t Rd, Rn;
5439        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5440        bool setflags;
5441        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5442        switch (encoding)
5443        {
5444        case eEncodingT1:
5445            Rd = Bits32(opcode, 11, 8);
5446            Rn = Bits32(opcode, 19, 16);
5447            setflags = BitIsSet(opcode, 20);
5448            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5449            if (BadReg(Rd) || BadReg(Rn))
5450                return false;
5451            break;
5452        case eEncodingA1:
5453            Rd = Bits32(opcode, 15, 12);
5454            Rn = Bits32(opcode, 19, 16);
5455            setflags = BitIsSet(opcode, 20);
5456            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5457            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5458            // TODO: Emulate SUBS PC, LR and related instructions.
5459            if (Rd == 15 && setflags)
5460                return false;
5461            break;
5462        default:
5463            return false;
5464        }
5465
5466        // Read the first operand.
5467        uint32_t val1 = ReadCoreReg(Rn, &success);
5468        if (!success)
5469            return false;
5470
5471        uint32_t result = val1 & ~imm32;
5472
5473        EmulateInstruction::Context context;
5474        context.type = EmulateInstruction::eContextImmediate;
5475        context.SetNoArgs ();
5476
5477        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5478            return false;
5479    }
5480    return true;
5481}
5482
5483// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5484// optionally-shifted register value, and writes the result to the destination register.
5485// It can optionally update the condition flags based on the result.
5486bool
5487EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5488{
5489#if 0
5490    // ARM pseudo code...
5491    if ConditionPassed() then
5492        EncodingSpecificOperations();
5493        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5494        result = R[n] AND NOT(shifted);
5495        if d == 15 then         // Can only occur for ARM encoding
5496            ALUWritePC(result); // setflags is always FALSE here
5497        else
5498            R[d] = result;
5499            if setflags then
5500                APSR.N = result<31>;
5501                APSR.Z = IsZeroBit(result);
5502                APSR.C = carry;
5503                // APSR.V unchanged
5504#endif
5505
5506    bool success = false;
5507
5508    if (ConditionPassed(opcode))
5509    {
5510        uint32_t Rd, Rn, Rm;
5511        ARM_ShifterType shift_t;
5512        uint32_t shift_n; // the shift applied to the value read from Rm
5513        bool setflags;
5514        uint32_t carry;
5515        switch (encoding)
5516        {
5517        case eEncodingT1:
5518            Rd = Rn = Bits32(opcode, 2, 0);
5519            Rm = Bits32(opcode, 5, 3);
5520            setflags = !InITBlock();
5521            shift_t = SRType_LSL;
5522            shift_n = 0;
5523            break;
5524        case eEncodingT2:
5525            Rd = Bits32(opcode, 11, 8);
5526            Rn = Bits32(opcode, 19, 16);
5527            Rm = Bits32(opcode, 3, 0);
5528            setflags = BitIsSet(opcode, 20);
5529            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5530            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5531                return false;
5532            break;
5533        case eEncodingA1:
5534            Rd = Bits32(opcode, 15, 12);
5535            Rn = Bits32(opcode, 19, 16);
5536            Rm = Bits32(opcode, 3, 0);
5537            setflags = BitIsSet(opcode, 20);
5538            shift_n = DecodeImmShiftARM(opcode, shift_t);
5539            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5540            // TODO: Emulate SUBS PC, LR and related instructions.
5541            if (Rd == 15 && setflags)
5542                return false;
5543            break;
5544        default:
5545            return false;
5546        }
5547
5548        // Read the first operand.
5549        uint32_t val1 = ReadCoreReg(Rn, &success);
5550        if (!success)
5551            return false;
5552
5553        // Read the second operand.
5554        uint32_t val2 = ReadCoreReg(Rm, &success);
5555        if (!success)
5556            return false;
5557
5558        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5559        uint32_t result = val1 & ~shifted;
5560
5561        EmulateInstruction::Context context;
5562        context.type = EmulateInstruction::eContextImmediate;
5563        context.SetNoArgs ();
5564
5565        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5566            return false;
5567    }
5568    return true;
5569}
5570
5571// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5572// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5573bool
5574EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5575{
5576#if 0
5577    if ConditionPassed() then
5578        EncodingSpecificOperations();
5579        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5580        address = if index then offset_addr else R[n];
5581        data = MemU[address,4];
5582        if wback then R[n] = offset_addr;
5583        if t == 15 then
5584            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5585        elsif UnalignedSupport() || address<1:0> = '00' then
5586            R[t] = data;
5587        else // Can only apply before ARMv7
5588            R[t] = ROR(data, 8*UInt(address<1:0>));
5589#endif
5590
5591    bool success = false;
5592
5593    if (ConditionPassed(opcode))
5594    {
5595        const uint32_t addr_byte_size = GetAddressByteSize();
5596
5597        uint32_t t;
5598        uint32_t n;
5599        uint32_t imm32;
5600        bool index;
5601        bool add;
5602        bool wback;
5603
5604        switch (encoding)
5605        {
5606            case eEncodingA1:
5607                // if Rn == '1111' then SEE LDR (literal);
5608                // if P == '0' && W == '1' then SEE LDRT;
5609                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5610                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5611                t = Bits32 (opcode, 15, 12);
5612                n = Bits32 (opcode, 19, 16);
5613                imm32 = Bits32 (opcode, 11, 0);
5614
5615                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5616                index = BitIsSet (opcode, 24);
5617                add = BitIsSet (opcode, 23);
5618                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5619
5620                // if wback && n == t then UNPREDICTABLE;
5621                if (wback && (n == t))
5622                    return false;
5623
5624                break;
5625
5626            default:
5627                return false;
5628        }
5629
5630        addr_t address;
5631        addr_t offset_addr;
5632        addr_t base_address = ReadCoreReg (n, &success);
5633        if (!success)
5634            return false;
5635
5636        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5637        if (add)
5638            offset_addr = base_address + imm32;
5639        else
5640            offset_addr = base_address - imm32;
5641
5642        // address = if index then offset_addr else R[n];
5643        if (index)
5644            address = offset_addr;
5645        else
5646            address = base_address;
5647
5648        // data = MemU[address,4];
5649
5650        Register base_reg;
5651        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5652
5653        EmulateInstruction::Context context;
5654        context.type = eContextRegisterLoad;
5655        context.SetRegisterPlusOffset (base_reg, address - base_address);
5656
5657        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5658        if (!success)
5659            return false;
5660
5661        // if wback then R[n] = offset_addr;
5662        if (wback)
5663        {
5664            context.type = eContextAdjustBaseRegister;
5665            context.SetAddress (offset_addr);
5666            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5667                return false;
5668        }
5669
5670        // if t == 15 then
5671        if (t == 15)
5672        {
5673            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5674            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5675            {
5676                // LoadWritePC (data);
5677                context.type = eContextRegisterLoad;
5678                context.SetRegisterPlusOffset (base_reg, address - base_address);
5679                LoadWritePC (context, data);
5680            }
5681            else
5682                  return false;
5683        }
5684        // elsif UnalignedSupport() || address<1:0> = '00' then
5685        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5686        {
5687            // R[t] = data;
5688            context.type = eContextRegisterLoad;
5689            context.SetRegisterPlusOffset (base_reg, address - base_address);
5690            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5691                return false;
5692        }
5693        // else // Can only apply before ARMv7
5694        else
5695        {
5696            // R[t] = ROR(data, 8*UInt(address<1:0>));
5697            data = ROR (data, Bits32 (address, 1, 0));
5698            context.type = eContextRegisterLoad;
5699            context.SetImmediate (data);
5700            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5701                return false;
5702        }
5703
5704    }
5705    return true;
5706}
5707
5708// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5709// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5710bool
5711EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5712{
5713#if 0
5714    if ConditionPassed() then
5715        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5716        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5717        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5718        address = if index then offset_addr else R[n];
5719        data = MemU[address,4];
5720        if wback then R[n] = offset_addr;
5721        if t == 15 then
5722            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5723        elsif UnalignedSupport() || address<1:0> = '00' then
5724            R[t] = data;
5725        else // Can only apply before ARMv7
5726            if CurrentInstrSet() == InstrSet_ARM then
5727                R[t] = ROR(data, 8*UInt(address<1:0>));
5728            else
5729                R[t] = bits(32) UNKNOWN;
5730#endif
5731
5732    bool success = false;
5733
5734    if (ConditionPassed(opcode))
5735    {
5736        const uint32_t addr_byte_size = GetAddressByteSize();
5737
5738        uint32_t t;
5739        uint32_t n;
5740        uint32_t m;
5741        bool index;
5742        bool add;
5743        bool wback;
5744        ARM_ShifterType shift_t;
5745        uint32_t shift_n;
5746
5747        switch (encoding)
5748        {
5749            case eEncodingT1:
5750                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5751                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5752                t = Bits32 (opcode, 2, 0);
5753                n = Bits32 (opcode, 5, 3);
5754                m = Bits32 (opcode, 8, 6);
5755
5756                // index = TRUE; add = TRUE; wback = FALSE;
5757                index = true;
5758                add = true;
5759                wback = false;
5760
5761                // (shift_t, shift_n) = (SRType_LSL, 0);
5762                shift_t = SRType_LSL;
5763                shift_n = 0;
5764
5765                break;
5766
5767            case eEncodingT2:
5768                // if Rn == '1111' then SEE LDR (literal);
5769                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5770                t = Bits32 (opcode, 15, 12);
5771                n = Bits32 (opcode, 19, 16);
5772                m = Bits32 (opcode, 3, 0);
5773
5774                // index = TRUE; add = TRUE; wback = FALSE;
5775                index = true;
5776                add = true;
5777                wback = false;
5778
5779                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5780                shift_t = SRType_LSL;
5781                shift_n = Bits32 (opcode, 5, 4);
5782
5783                // if BadReg(m) then UNPREDICTABLE;
5784                if (BadReg (m))
5785                    return false;
5786
5787                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5788                if ((t == 15) && InITBlock() && !LastInITBlock())
5789                    return false;
5790
5791                break;
5792
5793            case eEncodingA1:
5794            {
5795                // if P == '0' && W == '1' then SEE LDRT;
5796                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5797                t = Bits32 (opcode, 15, 12);
5798                n = Bits32 (opcode, 19, 16);
5799                m = Bits32 (opcode, 3, 0);
5800
5801                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5802                index = BitIsSet (opcode, 24);
5803                add = BitIsSet (opcode, 23);
5804                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5805
5806                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5807                uint32_t type = Bits32 (opcode, 6, 5);
5808                uint32_t imm5 = Bits32 (opcode, 11, 7);
5809                shift_n = DecodeImmShift (type, imm5, shift_t);
5810
5811                // if m == 15 then UNPREDICTABLE;
5812                if (m == 15)
5813                    return false;
5814
5815                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5816                if (wback && ((n == 15) || (n == t)))
5817                    return false;
5818            }
5819                break;
5820
5821
5822            default:
5823                return false;
5824        }
5825
5826        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5827        if (!success)
5828            return false;
5829
5830        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5831        if (!success)
5832            return false;
5833
5834        addr_t offset_addr;
5835        addr_t address;
5836
5837        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
5838        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C));
5839
5840        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5841        if (add)
5842            offset_addr = Rn + offset;
5843        else
5844            offset_addr = Rn - offset;
5845
5846        // address = if index then offset_addr else R[n];
5847            if (index)
5848                address = offset_addr;
5849            else
5850                address = Rn;
5851
5852        // data = MemU[address,4];
5853        Register base_reg;
5854        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5855
5856        EmulateInstruction::Context context;
5857        context.type = eContextRegisterLoad;
5858        context.SetRegisterPlusOffset (base_reg, address - Rn);
5859
5860        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5861        if (!success)
5862            return false;
5863
5864        // if wback then R[n] = offset_addr;
5865        if (wback)
5866        {
5867            context.type = eContextAdjustBaseRegister;
5868            context.SetAddress (offset_addr);
5869            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5870                return false;
5871        }
5872
5873        // if t == 15 then
5874        if (t == 15)
5875        {
5876            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5877            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5878            {
5879                context.type = eContextRegisterLoad;
5880                context.SetRegisterPlusOffset (base_reg, address - Rn);
5881                LoadWritePC (context, data);
5882            }
5883            else
5884                return false;
5885        }
5886        // elsif UnalignedSupport() || address<1:0> = '00' then
5887        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5888        {
5889            // R[t] = data;
5890            context.type = eContextRegisterLoad;
5891            context.SetRegisterPlusOffset (base_reg, address - Rn);
5892            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5893                return false;
5894        }
5895        else // Can only apply before ARMv7
5896        {
5897            // if CurrentInstrSet() == InstrSet_ARM then
5898            if (CurrentInstrSet () == eModeARM)
5899            {
5900                // R[t] = ROR(data, 8*UInt(address<1:0>));
5901                data = ROR (data, Bits32 (address, 1, 0));
5902                context.type = eContextRegisterLoad;
5903                context.SetImmediate (data);
5904                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5905                    return false;
5906            }
5907            else
5908            {
5909                // R[t] = bits(32) UNKNOWN;
5910                WriteBits32Unknown (t);
5911            }
5912        }
5913    }
5914    return true;
5915}
5916
5917// LDRB (immediate, Thumb)
5918bool
5919EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
5920{
5921#if 0
5922    if ConditionPassed() then
5923        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5924        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5925        address = if index then offset_addr else R[n];
5926        R[t] = ZeroExtend(MemU[address,1], 32);
5927        if wback then R[n] = offset_addr;
5928#endif
5929
5930    bool success = false;
5931
5932    if (ConditionPassed(opcode))
5933    {
5934        uint32_t t;
5935        uint32_t n;
5936        uint32_t imm32;
5937        bool index;
5938        bool add;
5939        bool wback;
5940
5941        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5942        switch (encoding)
5943        {
5944            case eEncodingT1:
5945                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5946                t = Bits32 (opcode, 2, 0);
5947                n = Bits32 (opcode, 5, 3);
5948                imm32 = Bits32 (opcode, 10, 6);
5949
5950                // index = TRUE; add = TRUE; wback = FALSE;
5951                index = true;
5952                add = true;
5953                wback= false;
5954
5955                break;
5956
5957            case eEncodingT2:
5958                // if Rt == '1111' then SEE PLD;
5959                // if Rn == '1111' then SEE LDRB (literal);
5960                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5961                t = Bits32 (opcode, 15, 12);
5962                n = Bits32 (opcode, 19, 16);
5963                imm32 = Bits32 (opcode, 11, 0);
5964
5965                // index = TRUE; add = TRUE; wback = FALSE;
5966                index = true;
5967                add = true;
5968                wback = false;
5969
5970                // if t == 13 then UNPREDICTABLE;
5971                if (t == 13)
5972                    return false;
5973
5974                break;
5975
5976            case eEncodingT3:
5977                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
5978                // if Rn == '1111' then SEE LDRB (literal);
5979                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
5980                // if P == '0' && W == '0' then UNDEFINED;
5981                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
5982                    return false;
5983
5984                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5985                t = Bits32 (opcode, 15, 12);
5986                n = Bits32 (opcode, 19, 16);
5987                imm32 = Bits32 (opcode, 7, 0);
5988
5989                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5990                index = BitIsSet (opcode, 10);
5991                add = BitIsSet (opcode, 9);
5992                wback = BitIsSet (opcode, 8);
5993
5994                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
5995                if (BadReg (t) || (wback && (n == t)))
5996                    return false;
5997
5998                break;
5999
6000            default:
6001                return false;
6002        }
6003
6004        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6005        if (!success)
6006            return false;
6007
6008        addr_t address;
6009        addr_t offset_addr;
6010
6011        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6012        if (add)
6013            offset_addr = Rn + imm32;
6014        else
6015            offset_addr = Rn - imm32;
6016
6017        // address = if index then offset_addr else R[n];
6018        if (index)
6019            address = offset_addr;
6020        else
6021            address = Rn;
6022
6023        // R[t] = ZeroExtend(MemU[address,1], 32);
6024        Register base_reg;
6025        Register data_reg;
6026        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6027        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
6028
6029        EmulateInstruction::Context context;
6030        context.type = eContextRegisterLoad;
6031        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6032
6033        uint64_t data = MemURead (context, address, 1, 0, &success);
6034        if (!success)
6035            return false;
6036
6037        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6038            return false;
6039
6040        // if wback then R[n] = offset_addr;
6041        if (wback)
6042        {
6043            context.type = eContextAdjustBaseRegister;
6044            context.SetAddress (offset_addr);
6045            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6046                return false;
6047        }
6048    }
6049    return true;
6050}
6051
6052// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6053// zero-extends it to form a 32-bit word and writes it to a register.
6054bool
6055EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6056{
6057#if 0
6058    if ConditionPassed() then
6059        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6060        base = Align(PC,4);
6061        address = if add then (base + imm32) else (base - imm32);
6062        R[t] = ZeroExtend(MemU[address,1], 32);
6063#endif
6064
6065    bool success = false;
6066
6067    if (ConditionPassed(opcode))
6068    {
6069        uint32_t t;
6070        uint32_t imm32;
6071        bool add;
6072        switch (encoding)
6073        {
6074            case eEncodingT1:
6075                // if Rt == '1111' then SEE PLD;
6076                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6077                t = Bits32 (opcode, 15, 12);
6078                imm32 = Bits32 (opcode, 11, 0);
6079                add = BitIsSet (opcode, 23);
6080
6081                // if t == 13 then UNPREDICTABLE;
6082                if (t == 13)
6083                    return false;
6084
6085                break;
6086
6087            case eEncodingA1:
6088                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6089                t = Bits32 (opcode, 15, 12);
6090                imm32 = Bits32 (opcode, 11, 0);
6091                add = BitIsSet (opcode, 23);
6092
6093                // if t == 15 then UNPREDICTABLE;
6094                if (t == 15)
6095                    return false;
6096                break;
6097
6098            default:
6099                return false;
6100        }
6101
6102        // base = Align(PC,4);
6103        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6104        if (!success)
6105            return false;
6106
6107        uint32_t base = AlignPC (pc_val);
6108
6109        addr_t address;
6110        // address = if add then (base + imm32) else (base - imm32);
6111        if (add)
6112            address = base + imm32;
6113        else
6114            address = base - imm32;
6115
6116        // R[t] = ZeroExtend(MemU[address,1], 32);
6117        EmulateInstruction::Context context;
6118        context.type = eContextRelativeBranchImmediate;
6119        context.SetImmediate (address - base);
6120
6121        uint64_t data = MemURead (context, address, 1, 0, &success);
6122        if (!success)
6123            return false;
6124
6125        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6126            return false;
6127    }
6128    return true;
6129}
6130
6131// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6132// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6133// optionally be shifted.
6134bool
6135EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6136{
6137#if 0
6138    if ConditionPassed() then
6139        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6140        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6141        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6142        address = if index then offset_addr else R[n];
6143        R[t] = ZeroExtend(MemU[address,1],32);
6144        if wback then R[n] = offset_addr;
6145#endif
6146
6147    bool success = false;
6148
6149    if (ConditionPassed(opcode))
6150    {
6151        uint32_t t;
6152        uint32_t n;
6153        uint32_t m;
6154        bool index;
6155        bool add;
6156        bool wback;
6157        ARM_ShifterType shift_t;
6158        uint32_t shift_n;
6159
6160        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6161        switch (encoding)
6162        {
6163            case eEncodingT1:
6164                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6165                t = Bits32 (opcode, 2, 0);
6166                n = Bits32 (opcode, 5, 3);
6167                m = Bits32 (opcode, 8, 6);
6168
6169                // index = TRUE; add = TRUE; wback = FALSE;
6170                index = true;
6171                add = true;
6172                wback = false;
6173
6174                // (shift_t, shift_n) = (SRType_LSL, 0);
6175                shift_t = SRType_LSL;
6176                shift_n = 0;
6177                break;
6178
6179            case eEncodingT2:
6180                // if Rt == '1111' then SEE PLD;
6181                // if Rn == '1111' then SEE LDRB (literal);
6182                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6183                t = Bits32 (opcode, 15, 12);
6184                n = Bits32 (opcode, 19, 16);
6185                m = Bits32 (opcode, 3, 0);
6186
6187                // index = TRUE; add = TRUE; wback = FALSE;
6188                index = true;
6189                add = true;
6190                wback = false;
6191
6192                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6193                shift_t = SRType_LSL;
6194                shift_n = Bits32 (opcode, 5, 4);
6195
6196                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6197                if ((t == 13) || BadReg (m))
6198                    return false;
6199                break;
6200
6201            case eEncodingA1:
6202            {
6203                // if P == '0' && W == '1' then SEE LDRBT;
6204                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6205                t = Bits32 (opcode, 15, 12);
6206                n = Bits32 (opcode, 19, 16);
6207                m = Bits32 (opcode, 3, 0);
6208
6209                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6210                index = BitIsSet (opcode, 24);
6211                add = BitIsSet (opcode, 23);
6212                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6213
6214                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6215                uint32_t type = Bits32 (opcode, 6, 5);
6216                uint32_t imm5 = Bits32 (opcode, 11, 7);
6217                shift_n = DecodeImmShift (type, imm5, shift_t);
6218
6219                // if t == 15 || m == 15 then UNPREDICTABLE;
6220                if ((t == 15) || (m == 15))
6221                    return false;
6222
6223                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6224                if (wback && ((n == 15) || (n == t)))
6225                    return false;
6226            }
6227                break;
6228
6229            default:
6230                return false;
6231        }
6232
6233        addr_t offset_addr;
6234        addr_t address;
6235
6236        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6237        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6238        if (!success)
6239            return false;
6240
6241        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6242
6243        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6244        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6245        if (!success)
6246            return false;
6247
6248        if (add)
6249            offset_addr = Rn + offset;
6250        else
6251            offset_addr = Rn - offset;
6252
6253        // address = if index then offset_addr else R[n];
6254        if (index)
6255            address = offset_addr;
6256        else
6257            address = Rn;
6258
6259        // R[t] = ZeroExtend(MemU[address,1],32);
6260        Register base_reg;
6261        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6262
6263        EmulateInstruction::Context context;
6264        context.type = eContextRegisterLoad;
6265        context.SetRegisterPlusOffset (base_reg, address - Rn);
6266
6267        uint64_t data = MemURead (context, address, 1, 0, &success);
6268        if (!success)
6269            return false;
6270
6271        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6272            return false;
6273
6274        // if wback then R[n] = offset_addr;
6275        if (wback)
6276        {
6277            context.type = eContextAdjustBaseRegister;
6278            context.SetAddress (offset_addr);
6279            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6280                return false;
6281        }
6282    }
6283    return true;
6284}
6285
6286// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6287// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6288// post-indexed, or pre-indexed addressing.
6289bool
6290EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6291{
6292#if 0
6293    if ConditionPassed() then
6294        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6295        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6296        address = if index then offset_addr else R[n];
6297        data = MemU[address,2];
6298        if wback then R[n] = offset_addr;
6299        if UnalignedSupport() || address<0> = '0' then
6300            R[t] = ZeroExtend(data, 32);
6301        else // Can only apply before ARMv7
6302            R[t] = bits(32) UNKNOWN;
6303#endif
6304
6305
6306    bool success = false;
6307
6308    if (ConditionPassed(opcode))
6309    {
6310        uint32_t t;
6311        uint32_t n;
6312        uint32_t imm32;
6313        bool index;
6314        bool add;
6315        bool wback;
6316
6317        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6318        switch (encoding)
6319        {
6320            case eEncodingT1:
6321                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6322                t = Bits32 (opcode, 2, 0);
6323                n = Bits32 (opcode, 5, 3);
6324                imm32 = Bits32 (opcode, 10, 6) << 1;
6325
6326                // index = TRUE; add = TRUE; wback = FALSE;
6327                index = true;
6328                add = true;
6329                wback = false;
6330
6331                break;
6332
6333            case eEncodingT2:
6334                // if Rt == '1111' then SEE "Unallocated memory hints";
6335                // if Rn == '1111' then SEE LDRH (literal);
6336                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6337                t = Bits32 (opcode, 15, 12);
6338                n = Bits32 (opcode, 19, 16);
6339                imm32 = Bits32 (opcode, 11, 0);
6340
6341                // index = TRUE; add = TRUE; wback = FALSE;
6342                index = true;
6343                add = true;
6344                wback = false;
6345
6346                // if t == 13 then UNPREDICTABLE;
6347                if (t == 13)
6348                    return false;
6349                break;
6350
6351            case eEncodingT3:
6352                // if Rn == '1111' then SEE LDRH (literal);
6353                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6354                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6355                // if P == '0' && W == '0' then UNDEFINED;
6356                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6357                    return false;
6358
6359                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6360                t = Bits32 (opcode, 15, 12);
6361                n = Bits32 (opcode, 19, 16);
6362                imm32 = Bits32 (opcode, 7, 0);
6363
6364                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6365                index = BitIsSet (opcode, 10);
6366                add = BitIsSet (opcode, 9);
6367                wback = BitIsSet (opcode, 8);
6368
6369                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6370                if (BadReg (t) || (wback && (n == t)))
6371                    return false;
6372                break;
6373
6374            default:
6375                return false;
6376        }
6377
6378        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6379        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6380        if (!success)
6381            return false;
6382
6383        addr_t offset_addr;
6384        addr_t address;
6385
6386        if (add)
6387            offset_addr = Rn + imm32;
6388        else
6389            offset_addr = Rn - imm32;
6390
6391        // address = if index then offset_addr else R[n];
6392        if (index)
6393            address = offset_addr;
6394        else
6395            address = Rn;
6396
6397        // data = MemU[address,2];
6398        Register base_reg;
6399        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6400
6401        EmulateInstruction::Context context;
6402        context.type = eContextRegisterLoad;
6403        context.SetRegisterPlusOffset (base_reg, address - Rn);
6404
6405        uint64_t data = MemURead (context, address, 2, 0, &success);
6406        if (!success)
6407            return false;
6408
6409        // if wback then R[n] = offset_addr;
6410        if (wback)
6411        {
6412            context.type = eContextAdjustBaseRegister;
6413            context.SetAddress (offset_addr);
6414            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6415                return false;
6416        }
6417
6418        // if UnalignedSupport() || address<0> = '0' then
6419        if (UnalignedSupport () || BitIsClear (address, 0))
6420        {
6421            // R[t] = ZeroExtend(data, 32);
6422            context.type = eContextRegisterLoad;
6423            context.SetRegisterPlusOffset (base_reg, address - Rn);
6424            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6425                return false;
6426        }
6427        else // Can only apply before ARMv7
6428        {
6429            // R[t] = bits(32) UNKNOWN;
6430            WriteBits32Unknown (t);
6431        }
6432    }
6433    return true;
6434}
6435
6436// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6437// zero-extends it to form a 32-bit word, and writes it to a register.
6438bool
6439EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6440{
6441#if 0
6442    if ConditionPassed() then
6443        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6444        base = Align(PC,4);
6445        address = if add then (base + imm32) else (base - imm32);
6446        data = MemU[address,2];
6447        if UnalignedSupport() || address<0> = '0' then
6448            R[t] = ZeroExtend(data, 32);
6449        else // Can only apply before ARMv7
6450            R[t] = bits(32) UNKNOWN;
6451#endif
6452
6453    bool success = false;
6454
6455    if (ConditionPassed(opcode))
6456    {
6457        uint32_t t;
6458        uint32_t imm32;
6459        bool add;
6460
6461        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6462        switch (encoding)
6463        {
6464            case eEncodingT1:
6465                // if Rt == '1111' then SEE "Unallocated memory hints";
6466                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6467                t = Bits32 (opcode, 15, 12);
6468                imm32 = Bits32 (opcode, 11, 0);
6469                add = BitIsSet (opcode, 23);
6470
6471                // if t == 13 then UNPREDICTABLE;
6472                if (t == 13)
6473                    return false;
6474
6475                break;
6476
6477            case eEncodingA1:
6478            {
6479                uint32_t imm4H = Bits32 (opcode, 11, 8);
6480                uint32_t imm4L = Bits32 (opcode, 3, 0);
6481
6482                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6483                t = Bits32 (opcode, 15, 12);
6484                imm32 = (imm4H << 4) | imm4L;
6485                add = BitIsSet (opcode, 23);
6486
6487                // if t == 15 then UNPREDICTABLE;
6488                if (t == 15)
6489                    return false;
6490                break;
6491            }
6492
6493            default:
6494                return false;
6495        }
6496
6497        // base = Align(PC,4);
6498        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6499        if (!success)
6500            return false;
6501
6502        addr_t base = AlignPC (pc_value);
6503        addr_t address;
6504
6505        // address = if add then (base + imm32) else (base - imm32);
6506        if (add)
6507            address = base + imm32;
6508        else
6509            address = base - imm32;
6510
6511        // data = MemU[address,2];
6512        Register base_reg;
6513        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
6514
6515        EmulateInstruction::Context context;
6516        context.type = eContextRegisterLoad;
6517        context.SetRegisterPlusOffset (base_reg, address - base);
6518
6519        uint64_t data = MemURead (context, address, 2, 0, &success);
6520        if (!success)
6521            return false;
6522
6523
6524        // if UnalignedSupport() || address<0> = '0' then
6525        if (UnalignedSupport () || BitIsClear (address, 0))
6526        {
6527            // R[t] = ZeroExtend(data, 32);
6528            context.type = eContextRegisterLoad;
6529            context.SetRegisterPlusOffset (base_reg, address - base);
6530            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6531                return false;
6532
6533        }
6534        else // Can only apply before ARMv7
6535        {
6536            // R[t] = bits(32) UNKNOWN;
6537            WriteBits32Unknown (t);
6538        }
6539    }
6540    return true;
6541}
6542
6543// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6544// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6545// be shifted left by 0, 1, 2, or 3 bits.
6546bool
6547EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6548{
6549#if 0
6550    if ConditionPassed() then
6551        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6552        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6553        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6554        address = if index then offset_addr else R[n];
6555        data = MemU[address,2];
6556        if wback then R[n] = offset_addr;
6557        if UnalignedSupport() || address<0> = '0' then
6558            R[t] = ZeroExtend(data, 32);
6559        else // Can only apply before ARMv7
6560            R[t] = bits(32) UNKNOWN;
6561#endif
6562
6563    bool success = false;
6564
6565    if (ConditionPassed(opcode))
6566    {
6567        uint32_t t;
6568        uint32_t n;
6569        uint32_t m;
6570        bool index;
6571        bool add;
6572        bool wback;
6573        ARM_ShifterType shift_t;
6574        uint32_t shift_n;
6575
6576        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6577        switch (encoding)
6578        {
6579            case eEncodingT1:
6580                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6581                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6582                t = Bits32 (opcode, 2, 0);
6583                n = Bits32 (opcode, 5, 3);
6584                m = Bits32 (opcode, 8, 6);
6585
6586                // index = TRUE; add = TRUE; wback = FALSE;
6587                index = true;
6588                add = true;
6589                wback = false;
6590
6591                // (shift_t, shift_n) = (SRType_LSL, 0);
6592                shift_t = SRType_LSL;
6593                shift_n = 0;
6594
6595                break;
6596
6597            case eEncodingT2:
6598                // if Rn == '1111' then SEE LDRH (literal);
6599                // if Rt == '1111' then SEE "Unallocated memory hints";
6600                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6601                t = Bits32 (opcode, 15, 12);
6602                n = Bits32 (opcode, 19, 16);
6603                m = Bits32 (opcode, 3, 0);
6604
6605                // index = TRUE; add = TRUE; wback = FALSE;
6606                index = true;
6607                add = true;
6608                wback = false;
6609
6610                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6611                shift_t = SRType_LSL;
6612                shift_n = Bits32 (opcode, 5, 4);
6613
6614                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6615                if ((t == 13) || BadReg (m))
6616                    return false;
6617                break;
6618
6619            case eEncodingA1:
6620                // if P == '0' && W == '1' then SEE LDRHT;
6621                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6622                t = Bits32 (opcode, 15, 12);
6623                n = Bits32 (opcode, 19, 16);
6624                m = Bits32 (opcode, 3, 0);
6625
6626                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6627                index = BitIsSet (opcode, 24);
6628                add = BitIsSet (opcode, 23);
6629                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6630
6631                // (shift_t, shift_n) = (SRType_LSL, 0);
6632                shift_t = SRType_LSL;
6633                shift_n = 0;
6634
6635                // if t == 15 || m == 15 then UNPREDICTABLE;
6636                if ((t == 15) || (m == 15))
6637                    return false;
6638
6639                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6640                if (wback && ((n == 15) || (n == t)))
6641                    return false;
6642
6643                break;
6644
6645            default:
6646                return false;
6647        }
6648
6649        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6650
6651        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6652        if (!success)
6653            return false;
6654
6655        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6656
6657        addr_t offset_addr;
6658        addr_t address;
6659
6660        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6661        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6662        if (!success)
6663            return false;
6664
6665        if (add)
6666            offset_addr = Rn + offset;
6667        else
6668            offset_addr = Rn - offset;
6669
6670        // address = if index then offset_addr else R[n];
6671        if (index)
6672            address = offset_addr;
6673        else
6674            address = Rn;
6675
6676        // data = MemU[address,2];
6677        Register base_reg;
6678        Register offset_reg;
6679        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6680        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
6681
6682        EmulateInstruction::Context context;
6683        context.type = eContextRegisterLoad;
6684        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6685        uint64_t data = MemURead (context, address, 2, 0, &success);
6686        if (!success)
6687            return false;
6688
6689        // if wback then R[n] = offset_addr;
6690        if (wback)
6691        {
6692            context.type = eContextAdjustBaseRegister;
6693            context.SetAddress (offset_addr);
6694            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6695                return false;
6696        }
6697
6698        // if UnalignedSupport() || address<0> = '0' then
6699        if (UnalignedSupport() || BitIsClear (address, 0))
6700        {
6701            // R[t] = ZeroExtend(data, 32);
6702            context.type = eContextRegisterLoad;
6703            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6704            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6705                return false;
6706        }
6707        else // Can only apply before ARMv7
6708        {
6709            // R[t] = bits(32) UNKNOWN;
6710            WriteBits32Unknown (t);
6711        }
6712    }
6713    return true;
6714}
6715
6716// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6717// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6718// or pre-indexed addressing.
6719bool
6720EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6721{
6722#if 0
6723    if ConditionPassed() then
6724        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6725        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6726        address = if index then offset_addr else R[n];
6727        R[t] = SignExtend(MemU[address,1], 32);
6728        if wback then R[n] = offset_addr;
6729#endif
6730
6731    bool success = false;
6732
6733    if (ConditionPassed(opcode))
6734    {
6735        uint32_t t;
6736        uint32_t n;
6737        uint32_t imm32;
6738        bool index;
6739        bool add;
6740        bool wback;
6741
6742        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6743        switch (encoding)
6744        {
6745            case eEncodingT1:
6746                // if Rt == '1111' then SEE PLI;
6747                // if Rn == '1111' then SEE LDRSB (literal);
6748                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6749                t = Bits32 (opcode, 15, 12);
6750                n = Bits32 (opcode, 19, 16);
6751                imm32 = Bits32 (opcode, 11, 0);
6752
6753                // index = TRUE; add = TRUE; wback = FALSE;
6754                index = true;
6755                add = true;
6756                wback = false;
6757
6758                // if t == 13 then UNPREDICTABLE;
6759                if (t == 13)
6760                    return false;
6761
6762                break;
6763
6764            case eEncodingT2:
6765                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6766                // if Rn == '1111' then SEE LDRSB (literal);
6767                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6768                // if P == '0' && W == '0' then UNDEFINED;
6769                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6770                    return false;
6771
6772                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6773                t = Bits32 (opcode, 15, 12);
6774                n = Bits32 (opcode, 19, 16);
6775                imm32 = Bits32 (opcode, 7, 0);
6776
6777                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6778                index = BitIsSet (opcode, 10);
6779                add = BitIsSet (opcode, 9);
6780                wback = BitIsSet (opcode, 8);
6781
6782                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6783                  if (((t == 13) || ((t == 15)
6784                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6785                      || (wback && (n == t)))
6786                    return false;
6787
6788                break;
6789
6790            case eEncodingA1:
6791            {
6792                // if Rn == '1111' then SEE LDRSB (literal);
6793                // if P == '0' && W == '1' then SEE LDRSBT;
6794                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6795                t = Bits32 (opcode, 15, 12);
6796                n = Bits32 (opcode, 19, 16);
6797
6798                uint32_t imm4H = Bits32 (opcode, 11, 8);
6799                uint32_t imm4L = Bits32 (opcode, 3, 0);
6800                imm32 = (imm4H << 4) | imm4L;
6801
6802                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6803                index = BitIsSet (opcode, 24);
6804                add = BitIsSet (opcode, 23);
6805                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6806
6807                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
6808                if ((t == 15) || (wback && (n == t)))
6809                    return false;
6810
6811                break;
6812            }
6813
6814            default:
6815                return false;
6816        }
6817
6818        uint64_t Rn = ReadCoreReg (n, &success);
6819        if (!success)
6820            return false;
6821
6822        addr_t offset_addr;
6823        addr_t address;
6824
6825        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6826        if (add)
6827            offset_addr = Rn + imm32;
6828        else
6829            offset_addr = Rn - imm32;
6830
6831        // address = if index then offset_addr else R[n];
6832        if (index)
6833            address = offset_addr;
6834        else
6835            address = Rn;
6836
6837        // R[t] = SignExtend(MemU[address,1], 32);
6838        Register base_reg;
6839        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6840
6841        EmulateInstruction::Context context;
6842        context.type = eContextRegisterLoad;
6843        context.SetRegisterPlusOffset (base_reg, address - Rn);
6844
6845        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
6846        if (!success)
6847            return false;
6848
6849        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
6850        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
6851            return false;
6852
6853        // if wback then R[n] = offset_addr;
6854        if (wback)
6855        {
6856            context.type = eContextAdjustBaseRegister;
6857            context.SetAddress (offset_addr);
6858            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6859                return false;
6860        }
6861    }
6862
6863    return true;
6864}
6865
6866// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6867// sign-extends it to form a 32-bit word, and writes tit to a register.
6868bool
6869EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6870{
6871#if 0
6872    if ConditionPassed() then
6873        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6874        base = Align(PC,4);
6875        address = if add then (base + imm32) else (base - imm32);
6876        R[t] = SignExtend(MemU[address,1], 32);
6877#endif
6878
6879    bool success = false;
6880
6881    if (ConditionPassed(opcode))
6882    {
6883        uint32_t t;
6884        uint32_t imm32;
6885        bool add;
6886
6887        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6888        switch (encoding)
6889        {
6890            case eEncodingT1:
6891                // if Rt == '1111' then SEE PLI;
6892                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6893                t = Bits32 (opcode, 15, 12);
6894                imm32 = Bits32 (opcode, 11, 0);
6895                add = BitIsSet (opcode, 23);
6896
6897                // if t == 13 then UNPREDICTABLE;
6898                if (t == 13)
6899                    return false;
6900
6901                break;
6902
6903            case eEncodingA1:
6904            {
6905                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6906                t = Bits32 (opcode, 15, 12);
6907                uint32_t imm4H = Bits32 (opcode, 11, 8);
6908                uint32_t imm4L = Bits32 (opcode, 3, 0);
6909                imm32 = (imm4H << 4) | imm4L;
6910                add = BitIsSet (opcode, 23);
6911
6912                // if t == 15 then UNPREDICTABLE;
6913                if (t == 15)
6914                    return false;
6915
6916                break;
6917            }
6918
6919            default:
6920                return false;
6921        }
6922
6923        // base = Align(PC,4);
6924        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6925        if (!success)
6926            return false;
6927        uint64_t base = AlignPC (pc_value);
6928
6929        // address = if add then (base + imm32) else (base - imm32);
6930        addr_t address;
6931        if (add)
6932            address = base + imm32;
6933        else
6934            address = base - imm32;
6935
6936        // R[t] = SignExtend(MemU[address,1], 32);
6937        Register base_reg;
6938        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
6939
6940        EmulateInstruction::Context context;
6941        context.type = eContextRegisterLoad;
6942        context.SetRegisterPlusOffset (base_reg, address - base);
6943
6944        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
6945        if (!success)
6946            return false;
6947
6948        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
6949        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
6950            return false;
6951    }
6952    return true;
6953}
6954
6955// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
6956// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
6957// shifted left by 0, 1, 2, or 3 bits.
6958bool
6959EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
6960{
6961#if 0
6962    if ConditionPassed() then
6963        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6964        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6965        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6966        address = if index then offset_addr else R[n];
6967        R[t] = SignExtend(MemU[address,1], 32);
6968        if wback then R[n] = offset_addr;
6969#endif
6970
6971    bool success = false;
6972
6973    if (ConditionPassed(opcode))
6974    {
6975        uint32_t t;
6976        uint32_t n;
6977        uint32_t m;
6978        bool index;
6979        bool add;
6980        bool wback;
6981        ARM_ShifterType shift_t;
6982        uint32_t shift_n;
6983
6984        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6985        switch (encoding)
6986        {
6987            case eEncodingT1:
6988                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6989                t = Bits32 (opcode, 2, 0);
6990                n = Bits32 (opcode, 5, 3);
6991                m = Bits32 (opcode, 8, 6);
6992
6993                // index = TRUE; add = TRUE; wback = FALSE;
6994                index = true;
6995                add = true;
6996                wback = false;
6997
6998                // (shift_t, shift_n) = (SRType_LSL, 0);
6999                shift_t = SRType_LSL;
7000                shift_n = 0;
7001
7002                break;
7003
7004            case eEncodingT2:
7005                // if Rt == '1111' then SEE PLI;
7006                // if Rn == '1111' then SEE LDRSB (literal);
7007                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7008                t = Bits32 (opcode, 15, 12);
7009                n = Bits32 (opcode, 19, 16);
7010                m = Bits32 (opcode, 3, 0);
7011
7012                // index = TRUE; add = TRUE; wback = FALSE;
7013                index = true;
7014                add = true;
7015                wback = false;
7016
7017                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7018                shift_t = SRType_LSL;
7019                shift_n = Bits32 (opcode, 5, 4);
7020
7021                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7022                if ((t == 13) || BadReg (m))
7023                    return false;
7024                break;
7025
7026            case eEncodingA1:
7027                // if P == '0' && W == '1' then SEE LDRSBT;
7028                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7029                t = Bits32 (opcode, 15, 12);
7030                n = Bits32 (opcode, 19, 16);
7031                m = Bits32 (opcode, 3, 0);
7032
7033                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7034                index = BitIsSet (opcode, 24);
7035                add = BitIsSet (opcode, 23);
7036                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7037
7038                // (shift_t, shift_n) = (SRType_LSL, 0);
7039                shift_t = SRType_LSL;
7040                shift_n = 0;
7041
7042                // if t == 15 || m == 15 then UNPREDICTABLE;
7043                if ((t == 15) || (m == 15))
7044                    return false;
7045
7046                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7047                if (wback && ((n == 15) || (n == t)))
7048                    return false;
7049                break;
7050
7051            default:
7052                return false;
7053        }
7054
7055        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7056        if (!success)
7057            return false;
7058
7059        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7060        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7061
7062        addr_t offset_addr;
7063        addr_t address;
7064
7065        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7066        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7067        if (!success)
7068            return false;
7069
7070        if (add)
7071            offset_addr = Rn + offset;
7072        else
7073            offset_addr = Rn - offset;
7074
7075        // address = if index then offset_addr else R[n];
7076        if (index)
7077            address = offset_addr;
7078        else
7079            address = Rn;
7080
7081        // R[t] = SignExtend(MemU[address,1], 32);
7082        Register base_reg;
7083        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7084        Register offset_reg;
7085        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7086
7087        EmulateInstruction::Context context;
7088        context.type = eContextRegisterLoad;
7089        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7090
7091        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7092        if (!success)
7093            return false;
7094
7095        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7096        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7097            return false;
7098
7099        // if wback then R[n] = offset_addr;
7100        if (wback)
7101        {
7102            context.type = eContextAdjustBaseRegister;
7103            context.SetAddress (offset_addr);
7104            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7105                return false;
7106        }
7107    }
7108    return true;
7109}
7110
7111// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7112// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7113// pre-indexed addressing.
7114bool
7115EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7116{
7117#if 0
7118    if ConditionPassed() then
7119        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7120        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7121        address = if index then offset_addr else R[n];
7122        data = MemU[address,2];
7123        if wback then R[n] = offset_addr;
7124        if UnalignedSupport() || address<0> = '0' then
7125            R[t] = SignExtend(data, 32);
7126        else // Can only apply before ARMv7
7127            R[t] = bits(32) UNKNOWN;
7128#endif
7129
7130    bool success = false;
7131
7132    if (ConditionPassed(opcode))
7133    {
7134        uint32_t t;
7135        uint32_t n;
7136        uint32_t imm32;
7137        bool index;
7138        bool add;
7139        bool wback;
7140
7141        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7142        switch (encoding)
7143        {
7144            case eEncodingT1:
7145                // if Rn == '1111' then SEE LDRSH (literal);
7146                // if Rt == '1111' then SEE "Unallocated memory hints";
7147                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7148                t = Bits32 (opcode, 15, 12);
7149                n = Bits32 (opcode, 19, 16);
7150                imm32 = Bits32 (opcode, 11, 0);
7151
7152                // index = TRUE; add = TRUE; wback = FALSE;
7153                index = true;
7154                add = true;
7155                wback = false;
7156
7157                // if t == 13 then UNPREDICTABLE;
7158                if (t == 13)
7159                    return false;
7160
7161                break;
7162
7163            case eEncodingT2:
7164                // if Rn == '1111' then SEE LDRSH (literal);
7165                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7166                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7167                // if P == '0' && W == '0' then UNDEFINED;
7168                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7169                  return false;
7170
7171                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7172                t = Bits32 (opcode, 15, 12);
7173                n = Bits32 (opcode, 19, 16);
7174                imm32 = Bits32 (opcode, 7, 0);
7175
7176                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7177                index = BitIsSet (opcode, 10);
7178                add = BitIsSet (opcode, 9);
7179                wback = BitIsSet (opcode, 8);
7180
7181                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7182                if (BadReg (t) || (wback && (n == t)))
7183                    return false;
7184
7185                break;
7186
7187            case eEncodingA1:
7188            {
7189                // if Rn == '1111' then SEE LDRSH (literal);
7190                // if P == '0' && W == '1' then SEE LDRSHT;
7191                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7192                t = Bits32 (opcode, 15, 12);
7193                n = Bits32 (opcode, 19, 16);
7194                uint32_t imm4H = Bits32 (opcode, 11,8);
7195                uint32_t imm4L = Bits32 (opcode, 3, 0);
7196                imm32 = (imm4H << 4) | imm4L;
7197
7198                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7199                index = BitIsSet (opcode, 24);
7200                add = BitIsSet (opcode, 23);
7201                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7202
7203                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7204                if ((t == 15) || (wback && (n == t)))
7205                    return false;
7206
7207                break;
7208            }
7209
7210            default:
7211                return false;
7212        }
7213
7214        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7215        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7216        if (!success)
7217            return false;
7218
7219        addr_t offset_addr;
7220        if (add)
7221            offset_addr = Rn + imm32;
7222        else
7223            offset_addr = Rn - imm32;
7224
7225        // address = if index then offset_addr else R[n];
7226        addr_t address;
7227        if (index)
7228            address = offset_addr;
7229        else
7230            address = Rn;
7231
7232        // data = MemU[address,2];
7233        Register base_reg;
7234        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7235
7236        EmulateInstruction::Context context;
7237        context.type = eContextRegisterLoad;
7238        context.SetRegisterPlusOffset (base_reg, address - Rn);
7239
7240        uint64_t data = MemURead (context, address, 2, 0, &success);
7241        if (!success)
7242            return false;
7243
7244        // if wback then R[n] = offset_addr;
7245        if (wback)
7246        {
7247            context.type = eContextAdjustBaseRegister;
7248            context.SetAddress (offset_addr);
7249            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7250                return false;
7251        }
7252
7253        // if UnalignedSupport() || address<0> = '0' then
7254        if (UnalignedSupport() || BitIsClear (address, 0))
7255        {
7256            // R[t] = SignExtend(data, 32);
7257            int64_t signed_data = llvm::SignExtend64<16>(data);
7258            context.type = eContextRegisterLoad;
7259            context.SetRegisterPlusOffset (base_reg, address - Rn);
7260            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7261                return false;
7262        }
7263        else // Can only apply before ARMv7
7264        {
7265            // R[t] = bits(32) UNKNOWN;
7266            WriteBits32Unknown (t);
7267        }
7268    }
7269    return true;
7270}
7271
7272// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7273// sign-extends it to from a 32-bit word, and writes it to a register.
7274bool
7275EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7276{
7277#if 0
7278    if ConditionPassed() then
7279        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7280        base = Align(PC,4);
7281        address = if add then (base + imm32) else (base - imm32);
7282        data = MemU[address,2];
7283        if UnalignedSupport() || address<0> = '0' then
7284            R[t] = SignExtend(data, 32);
7285        else // Can only apply before ARMv7
7286            R[t] = bits(32) UNKNOWN;
7287#endif
7288
7289    bool success = false;
7290
7291    if (ConditionPassed(opcode))
7292    {
7293        uint32_t t;
7294        uint32_t imm32;
7295        bool add;
7296
7297        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7298        switch (encoding)
7299        {
7300            case eEncodingT1:
7301                // if Rt == '1111' then SEE "Unallocated memory hints";
7302                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7303                t = Bits32  (opcode, 15, 12);
7304                imm32 = Bits32 (opcode, 11, 0);
7305                add = BitIsSet (opcode, 23);
7306
7307                // if t == 13 then UNPREDICTABLE;
7308                if (t == 13)
7309                    return false;
7310
7311                break;
7312
7313            case eEncodingA1:
7314            {
7315                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7316                t = Bits32 (opcode, 15, 12);
7317                uint32_t imm4H = Bits32 (opcode, 11, 8);
7318                uint32_t imm4L = Bits32 (opcode, 3, 0);
7319                imm32 = (imm4H << 4) | imm4L;
7320                add = BitIsSet (opcode, 23);
7321
7322                // if t == 15 then UNPREDICTABLE;
7323                if (t == 15)
7324                    return false;
7325
7326                break;
7327            }
7328            default:
7329                return false;
7330        }
7331
7332        // base = Align(PC,4);
7333        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7334        if (!success)
7335            return false;
7336
7337        uint64_t base = AlignPC (pc_value);
7338
7339        addr_t address;
7340        // address = if add then (base + imm32) else (base - imm32);
7341        if (add)
7342            address = base + imm32;
7343        else
7344            address = base - imm32;
7345
7346        // data = MemU[address,2];
7347        Register base_reg;
7348        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7349
7350        EmulateInstruction::Context context;
7351        context.type = eContextRegisterLoad;
7352        context.SetRegisterPlusOffset (base_reg, imm32);
7353
7354        uint64_t data = MemURead (context, address, 2, 0, &success);
7355        if (!success)
7356            return false;
7357
7358        // if UnalignedSupport() || address<0> = '0' then
7359        if (UnalignedSupport() || BitIsClear (address, 0))
7360        {
7361            // R[t] = SignExtend(data, 32);
7362            int64_t signed_data = llvm::SignExtend64<16>(data);
7363            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7364                return false;
7365        }
7366        else // Can only apply before ARMv7
7367        {
7368            // R[t] = bits(32) UNKNOWN;
7369            WriteBits32Unknown (t);
7370        }
7371    }
7372    return true;
7373}
7374
7375// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7376// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7377// shifted left by 0, 1, 2, or 3 bits.
7378bool
7379EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7380{
7381#if 0
7382    if ConditionPassed() then
7383        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7384        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7385        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7386        address = if index then offset_addr else R[n];
7387        data = MemU[address,2];
7388        if wback then R[n] = offset_addr;
7389        if UnalignedSupport() || address<0> = '0' then
7390            R[t] = SignExtend(data, 32);
7391        else // Can only apply before ARMv7
7392            R[t] = bits(32) UNKNOWN;
7393#endif
7394
7395    bool success = false;
7396
7397    if (ConditionPassed(opcode))
7398    {
7399        uint32_t t;
7400        uint32_t n;
7401        uint32_t m;
7402        bool index;
7403        bool add;
7404        bool wback;
7405        ARM_ShifterType shift_t;
7406        uint32_t shift_n;
7407
7408        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7409        switch (encoding)
7410        {
7411            case eEncodingT1:
7412                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7413                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7414                t = Bits32 (opcode, 2, 0);
7415                n = Bits32 (opcode, 5, 3);
7416                m = Bits32 (opcode, 8, 6);
7417
7418                // index = TRUE; add = TRUE; wback = FALSE;
7419                index = true;
7420                add = true;
7421                wback = false;
7422
7423                // (shift_t, shift_n) = (SRType_LSL, 0);
7424                shift_t = SRType_LSL;
7425                shift_n = 0;
7426
7427                break;
7428
7429            case eEncodingT2:
7430                // if Rn == '1111' then SEE LDRSH (literal);
7431                // if Rt == '1111' then SEE "Unallocated memory hints";
7432                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7433                t = Bits32 (opcode, 15, 12);
7434                n = Bits32 (opcode, 19, 16);
7435                m = Bits32 (opcode, 3, 0);
7436
7437                // index = TRUE; add = TRUE; wback = FALSE;
7438                index = true;
7439                add = true;
7440                wback = false;
7441
7442                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7443                shift_t = SRType_LSL;
7444                shift_n = Bits32 (opcode, 5, 4);
7445
7446                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7447                if ((t == 13) || BadReg (m))
7448                    return false;
7449
7450                break;
7451
7452            case eEncodingA1:
7453                // if P == '0' && W == '1' then SEE LDRSHT;
7454                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7455                t = Bits32 (opcode, 15, 12);
7456                n = Bits32 (opcode, 19, 16);
7457                m = Bits32 (opcode, 3, 0);
7458
7459                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7460                index = BitIsSet (opcode, 24);
7461                add = BitIsSet (opcode, 23);
7462                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7463
7464                // (shift_t, shift_n) = (SRType_LSL, 0);
7465                shift_t = SRType_LSL;
7466                shift_n = 0;
7467
7468                // if t == 15 || m == 15 then UNPREDICTABLE;
7469                if ((t == 15) || (m == 15))
7470                    return false;
7471
7472                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7473                if (wback && ((n == 15) || (n == t)))
7474                    return false;
7475
7476                break;
7477
7478            default:
7479                break;
7480        }
7481
7482        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7483        if (!success)
7484            return false;
7485
7486        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7487        if (!success)
7488            return false;
7489
7490        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7491        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7492
7493        addr_t offset_addr;
7494        addr_t address;
7495
7496        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7497        if (add)
7498            offset_addr = Rn + offset;
7499        else
7500            offset_addr = Rn - offset;
7501
7502        // address = if index then offset_addr else R[n];
7503        if (index)
7504            address = offset_addr;
7505        else
7506            address = Rn;
7507
7508        // data = MemU[address,2];
7509        Register base_reg;
7510        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7511
7512        Register offset_reg;
7513        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7514
7515        EmulateInstruction::Context context;
7516        context.type = eContextRegisterLoad;
7517        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7518
7519        uint64_t data = MemURead (context, address, 2, 0, &success);
7520        if (!success)
7521            return false;
7522
7523        // if wback then R[n] = offset_addr;
7524        if (wback)
7525        {
7526            context.type = eContextAdjustBaseRegister;
7527            context.SetAddress (offset_addr);
7528            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7529                return false;
7530        }
7531
7532        // if UnalignedSupport() || address<0> = '0' then
7533        if (UnalignedSupport() || BitIsClear (address, 0))
7534        {
7535            // R[t] = SignExtend(data, 32);
7536            context.type = eContextRegisterLoad;
7537            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7538
7539            int64_t signed_data = llvm::SignExtend64<16>(data);
7540            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7541                return false;
7542        }
7543        else // Can only apply before ARMv7
7544        {
7545            // R[t] = bits(32) UNKNOWN;
7546            WriteBits32Unknown (t);
7547        }
7548    }
7549    return true;
7550}
7551
7552// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7553// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7554bool
7555EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7556{
7557#if 0
7558    if ConditionPassed() then
7559        EncodingSpecificOperations();
7560        rotated = ROR(R[m], rotation);
7561        R[d] = SignExtend(rotated<7:0>, 32);
7562#endif
7563
7564    bool success = false;
7565
7566    if (ConditionPassed(opcode))
7567    {
7568        uint32_t d;
7569        uint32_t m;
7570        uint32_t rotation;
7571
7572        // EncodingSpecificOperations();
7573        switch (encoding)
7574        {
7575            case eEncodingT1:
7576                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7577                d = Bits32 (opcode, 2, 0);
7578                m = Bits32 (opcode, 5, 3);
7579                rotation = 0;
7580
7581                break;
7582
7583            case eEncodingT2:
7584                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7585                d = Bits32 (opcode, 11, 8);
7586                m = Bits32 (opcode, 3, 0);
7587                rotation = Bits32 (opcode, 5, 4) << 3;
7588
7589                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7590                if (BadReg (d) || BadReg (m))
7591                    return false;
7592
7593                break;
7594
7595            case eEncodingA1:
7596                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7597                d = Bits32 (opcode, 15, 12);
7598                m = Bits32 (opcode, 3, 0);
7599                rotation = Bits32 (opcode, 11, 10) << 3;
7600
7601                // if d == 15 || m == 15 then UNPREDICTABLE;
7602                if ((d == 15) || (m == 15))
7603                    return false;
7604
7605                break;
7606
7607            default:
7608                return false;
7609        }
7610
7611        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7612        if (!success)
7613            return false;
7614
7615        // rotated = ROR(R[m], rotation);
7616        uint64_t rotated = ROR (Rm, rotation);
7617
7618        // R[d] = SignExtend(rotated<7:0>, 32);
7619        int64_t data = llvm::SignExtend64<8>(rotated);
7620
7621        Register source_reg;
7622        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7623
7624        EmulateInstruction::Context context;
7625        context.type = eContextRegisterLoad;
7626        context.SetRegister (source_reg);
7627
7628        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7629            return false;
7630    }
7631    return true;
7632}
7633
7634// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7635// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7636bool
7637EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7638{
7639#if 0
7640    if ConditionPassed() then
7641        EncodingSpecificOperations();
7642        rotated = ROR(R[m], rotation);
7643        R[d] = SignExtend(rotated<15:0>, 32);
7644#endif
7645
7646    bool success = false;
7647
7648    if (ConditionPassed(opcode))
7649    {
7650        uint32_t d;
7651        uint32_t m;
7652        uint32_t rotation;
7653
7654        // EncodingSpecificOperations();
7655        switch (encoding)
7656        {
7657            case eEncodingT1:
7658                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7659                d = Bits32 (opcode, 2, 0);
7660                m = Bits32 (opcode, 5, 3);
7661                rotation = 0;
7662
7663                break;
7664
7665            case eEncodingT2:
7666                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7667                d = Bits32 (opcode, 11, 8);
7668                m = Bits32 (opcode, 3, 0);
7669                rotation = Bits32 (opcode, 5, 4) << 3;
7670
7671                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7672                if (BadReg (d) || BadReg (m))
7673                    return false;
7674
7675                break;
7676
7677            case eEncodingA1:
7678                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7679                d = Bits32 (opcode, 15, 12);
7680                m = Bits32 (opcode, 3, 0);
7681                rotation = Bits32 (opcode, 11, 10) << 3;
7682
7683                // if d == 15 || m == 15 then UNPREDICTABLE;
7684                if ((d == 15) || (m == 15))
7685                    return false;
7686
7687                break;
7688
7689            default:
7690                return false;
7691        }
7692
7693        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7694        if (!success)
7695            return false;
7696
7697        // rotated = ROR(R[m], rotation);
7698        uint64_t rotated = ROR (Rm, rotation);
7699
7700        // R[d] = SignExtend(rotated<15:0>, 32);
7701        Register source_reg;
7702        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7703
7704        EmulateInstruction::Context context;
7705        context.type = eContextRegisterLoad;
7706        context.SetRegister (source_reg);
7707
7708        int64_t data = llvm::SignExtend64<16> (rotated);
7709        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7710            return false;
7711    }
7712
7713    return true;
7714}
7715
7716// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7717// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7718bool
7719EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7720{
7721#if 0
7722    if ConditionPassed() then
7723        EncodingSpecificOperations();
7724        rotated = ROR(R[m], rotation);
7725        R[d] = ZeroExtend(rotated<7:0>, 32);
7726#endif
7727
7728    bool success = false;
7729
7730    if (ConditionPassed(opcode))
7731    {
7732        uint32_t d;
7733        uint32_t m;
7734        uint32_t rotation;
7735
7736        // EncodingSpecificOperations();
7737        switch (encoding)
7738        {
7739            case eEncodingT1:
7740                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7741                d = Bits32 (opcode, 2, 0);
7742                m = Bits32 (opcode, 5, 3);
7743                rotation = 0;
7744
7745                break;
7746
7747            case eEncodingT2:
7748                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7749                d = Bits32 (opcode, 11, 8);
7750                m = Bits32 (opcode, 3, 0);
7751                  rotation = Bits32 (opcode, 5, 4) << 3;
7752
7753                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7754                if (BadReg (d) || BadReg (m))
7755                  return false;
7756
7757                break;
7758
7759            case eEncodingA1:
7760                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7761                d = Bits32 (opcode, 15, 12);
7762                m = Bits32 (opcode, 3, 0);
7763                rotation = Bits32 (opcode, 11, 10) << 3;
7764
7765                // if d == 15 || m == 15 then UNPREDICTABLE;
7766                if ((d == 15) || (m == 15))
7767                    return false;
7768
7769                break;
7770
7771            default:
7772                return false;
7773        }
7774
7775        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7776        if (!success)
7777            return false;
7778
7779        // rotated = ROR(R[m], rotation);
7780        uint64_t rotated = ROR (Rm, rotation);
7781
7782        // R[d] = ZeroExtend(rotated<7:0>, 32);
7783        Register source_reg;
7784        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7785
7786        EmulateInstruction::Context context;
7787        context.type = eContextRegisterLoad;
7788        context.SetRegister (source_reg);
7789
7790        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7791            return false;
7792    }
7793    return true;
7794}
7795
7796// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
7797// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7798bool
7799EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
7800{
7801#if 0
7802    if ConditionPassed() then
7803        EncodingSpecificOperations();
7804        rotated = ROR(R[m], rotation);
7805        R[d] = ZeroExtend(rotated<15:0>, 32);
7806#endif
7807
7808    bool success = false;
7809
7810    if (ConditionPassed(opcode))
7811    {
7812        uint32_t d;
7813        uint32_t m;
7814        uint32_t rotation;
7815
7816        switch (encoding)
7817        {
7818            case eEncodingT1:
7819                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7820                d = Bits32 (opcode, 2, 0);
7821                m = Bits32 (opcode, 5, 3);
7822                rotation = 0;
7823
7824                break;
7825
7826            case eEncodingT2:
7827                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7828                d = Bits32 (opcode, 11, 8);
7829                m = Bits32 (opcode, 3, 0);
7830                rotation = Bits32 (opcode, 5, 4) << 3;
7831
7832                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7833                if (BadReg (d) || BadReg (m))
7834                  return false;
7835
7836                break;
7837
7838            case eEncodingA1:
7839                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7840                d = Bits32 (opcode, 15, 12);
7841                m = Bits32 (opcode, 3, 0);
7842                rotation = Bits32 (opcode, 11, 10) << 3;
7843
7844                // if d == 15 || m == 15 then UNPREDICTABLE;
7845                if ((d == 15) || (m == 15))
7846                    return false;
7847
7848                break;
7849
7850            default:
7851                return false;
7852        }
7853
7854        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7855        if (!success)
7856            return false;
7857
7858        // rotated = ROR(R[m], rotation);
7859        uint64_t rotated = ROR (Rm, rotation);
7860
7861        // R[d] = ZeroExtend(rotated<15:0>, 32);
7862        Register source_reg;
7863        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7864
7865        EmulateInstruction::Context context;
7866        context.type = eContextRegisterLoad;
7867        context.SetRegister (source_reg);
7868
7869        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
7870            return false;
7871    }
7872    return true;
7873}
7874
7875// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
7876// word respectively.
7877bool
7878EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
7879{
7880#if 0
7881    if ConditionPassed() then
7882        EncodingSpecificOperations();
7883        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
7884            UNPREDICTABLE;
7885        else
7886            address = if increment then R[n] else R[n]-8;
7887            if wordhigher then address = address+4;
7888            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
7889            BranchWritePC(MemA[address,4]);
7890            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
7891#endif
7892
7893    bool success = false;
7894
7895    if (ConditionPassed(opcode))
7896    {
7897        uint32_t n;
7898        bool wback;
7899        bool increment;
7900        bool wordhigher;
7901
7902        // EncodingSpecificOperations();
7903        switch (encoding)
7904        {
7905            case eEncodingT1:
7906                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
7907                n = Bits32 (opcode, 19, 16);
7908                wback = BitIsSet (opcode, 21);
7909                increment = false;
7910                wordhigher = false;
7911
7912                // if n == 15 then UNPREDICTABLE;
7913                if (n == 15)
7914                    return false;
7915
7916                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7917                if (InITBlock() && !LastInITBlock())
7918                    return false;
7919
7920                break;
7921
7922            case eEncodingT2:
7923                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
7924                n = Bits32 (opcode, 19, 16);
7925                wback = BitIsSet (opcode, 21);
7926                increment = true;
7927                wordhigher = false;
7928
7929                // if n == 15 then UNPREDICTABLE;
7930                if (n == 15)
7931                    return false;
7932
7933                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7934                if (InITBlock() && !LastInITBlock())
7935                    return false;
7936
7937                break;
7938
7939            case eEncodingA1:
7940                // n = UInt(Rn);
7941                n = Bits32 (opcode, 19, 16);
7942
7943                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
7944                wback = BitIsSet (opcode, 21);
7945                increment = BitIsSet (opcode, 23);
7946                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
7947
7948                // if n == 15 then UNPREDICTABLE;
7949                if (n == 15)
7950                    return false;
7951
7952                break;
7953
7954            default:
7955                return false;
7956        }
7957
7958        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
7959        if (!CurrentModeIsPrivileged ())
7960            // UNPREDICTABLE;
7961            return false;
7962        else
7963        {
7964            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7965            if (!success)
7966                return false;
7967
7968            addr_t address;
7969            // address = if increment then R[n] else R[n]-8;
7970            if (increment)
7971                address = Rn;
7972            else
7973                address = Rn - 8;
7974
7975            // if wordhigher then address = address+4;
7976            if (wordhigher)
7977                address = address + 4;
7978
7979            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
7980            Register base_reg;
7981            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7982
7983            EmulateInstruction::Context context;
7984            context.type = eContextReturnFromException;
7985            context.SetRegisterPlusOffset (base_reg, address - Rn);
7986
7987            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
7988            if (!success)
7989                return false;
7990
7991            CPSRWriteByInstr (data, 15, true);
7992
7993            // BranchWritePC(MemA[address,4]);
7994            uint64_t data2 = MemARead (context, address, 4, 0, &success);
7995            if (!success)
7996                return false;
7997
7998            BranchWritePC (context, data2);
7999
8000            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8001            if (wback)
8002            {
8003                context.type = eContextAdjustBaseRegister;
8004                if (increment)
8005                {
8006                    context.SetOffset (8);
8007                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8008                        return false;
8009                }
8010                else
8011                {
8012                    context.SetOffset (-8);
8013                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8014                        return false;
8015                }
8016            } // if wback
8017        }
8018    } // if ConditionPassed()
8019    return true;
8020}
8021
8022// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8023// and writes the result to the destination register.  It can optionally update the condition flags based on
8024// the result.
8025bool
8026EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8027{
8028#if 0
8029    // ARM pseudo code...
8030    if ConditionPassed() then
8031        EncodingSpecificOperations();
8032        result = R[n] EOR imm32;
8033        if d == 15 then         // Can only occur for ARM encoding
8034            ALUWritePC(result); // setflags is always FALSE here
8035        else
8036            R[d] = result;
8037            if setflags then
8038                APSR.N = result<31>;
8039                APSR.Z = IsZeroBit(result);
8040                APSR.C = carry;
8041                // APSR.V unchanged
8042#endif
8043
8044    bool success = false;
8045
8046    if (ConditionPassed(opcode))
8047    {
8048        uint32_t Rd, Rn;
8049        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8050        bool setflags;
8051        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8052        switch (encoding)
8053        {
8054        case eEncodingT1:
8055            Rd = Bits32(opcode, 11, 8);
8056            Rn = Bits32(opcode, 19, 16);
8057            setflags = BitIsSet(opcode, 20);
8058            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8059            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8060            if (Rd == 15 && setflags)
8061                return EmulateTEQImm (opcode, eEncodingT1);
8062            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8063                return false;
8064            break;
8065        case eEncodingA1:
8066            Rd = Bits32(opcode, 15, 12);
8067            Rn = Bits32(opcode, 19, 16);
8068            setflags = BitIsSet(opcode, 20);
8069            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8070            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8071            // TODO: Emulate SUBS PC, LR and related instructions.
8072            if (Rd == 15 && setflags)
8073                return false;
8074            break;
8075        default:
8076            return false;
8077        }
8078
8079        // Read the first operand.
8080        uint32_t val1 = ReadCoreReg(Rn, &success);
8081        if (!success)
8082            return false;
8083
8084        uint32_t result = val1 ^ imm32;
8085
8086        EmulateInstruction::Context context;
8087        context.type = EmulateInstruction::eContextImmediate;
8088        context.SetNoArgs ();
8089
8090        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8091            return false;
8092    }
8093    return true;
8094}
8095
8096// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8097// optionally-shifted register value, and writes the result to the destination register.
8098// It can optionally update the condition flags based on the result.
8099bool
8100EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8101{
8102#if 0
8103    // ARM pseudo code...
8104    if ConditionPassed() then
8105        EncodingSpecificOperations();
8106        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8107        result = R[n] EOR shifted;
8108        if d == 15 then         // Can only occur for ARM encoding
8109            ALUWritePC(result); // setflags is always FALSE here
8110        else
8111            R[d] = result;
8112            if setflags then
8113                APSR.N = result<31>;
8114                APSR.Z = IsZeroBit(result);
8115                APSR.C = carry;
8116                // APSR.V unchanged
8117#endif
8118
8119    bool success = false;
8120
8121    if (ConditionPassed(opcode))
8122    {
8123        uint32_t Rd, Rn, Rm;
8124        ARM_ShifterType shift_t;
8125        uint32_t shift_n; // the shift applied to the value read from Rm
8126        bool setflags;
8127        uint32_t carry;
8128        switch (encoding)
8129        {
8130        case eEncodingT1:
8131            Rd = Rn = Bits32(opcode, 2, 0);
8132            Rm = Bits32(opcode, 5, 3);
8133            setflags = !InITBlock();
8134            shift_t = SRType_LSL;
8135            shift_n = 0;
8136            break;
8137        case eEncodingT2:
8138            Rd = Bits32(opcode, 11, 8);
8139            Rn = Bits32(opcode, 19, 16);
8140            Rm = Bits32(opcode, 3, 0);
8141            setflags = BitIsSet(opcode, 20);
8142            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8143            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8144            if (Rd == 15 && setflags)
8145                return EmulateTEQReg (opcode, eEncodingT1);
8146            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8147                return false;
8148            break;
8149        case eEncodingA1:
8150            Rd = Bits32(opcode, 15, 12);
8151            Rn = Bits32(opcode, 19, 16);
8152            Rm = Bits32(opcode, 3, 0);
8153            setflags = BitIsSet(opcode, 20);
8154            shift_n = DecodeImmShiftARM(opcode, shift_t);
8155            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8156            // TODO: Emulate SUBS PC, LR and related instructions.
8157            if (Rd == 15 && setflags)
8158                return false;
8159            break;
8160        default:
8161            return false;
8162        }
8163
8164        // Read the first operand.
8165        uint32_t val1 = ReadCoreReg(Rn, &success);
8166        if (!success)
8167            return false;
8168
8169        // Read the second operand.
8170        uint32_t val2 = ReadCoreReg(Rm, &success);
8171        if (!success)
8172            return false;
8173
8174        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8175        uint32_t result = val1 ^ shifted;
8176
8177        EmulateInstruction::Context context;
8178        context.type = EmulateInstruction::eContextImmediate;
8179        context.SetNoArgs ();
8180
8181        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8182            return false;
8183    }
8184    return true;
8185}
8186
8187// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8188// writes the result to the destination register.  It can optionally update the condition flags based
8189// on the result.
8190bool
8191EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8192{
8193#if 0
8194    // ARM pseudo code...
8195    if ConditionPassed() then
8196        EncodingSpecificOperations();
8197        result = R[n] OR imm32;
8198        if d == 15 then         // Can only occur for ARM encoding
8199            ALUWritePC(result); // setflags is always FALSE here
8200        else
8201            R[d] = result;
8202            if setflags then
8203                APSR.N = result<31>;
8204                APSR.Z = IsZeroBit(result);
8205                APSR.C = carry;
8206                // APSR.V unchanged
8207#endif
8208
8209    bool success = false;
8210
8211    if (ConditionPassed(opcode))
8212    {
8213        uint32_t Rd, Rn;
8214        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8215        bool setflags;
8216        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8217        switch (encoding)
8218        {
8219        case eEncodingT1:
8220            Rd = Bits32(opcode, 11, 8);
8221            Rn = Bits32(opcode, 19, 16);
8222            setflags = BitIsSet(opcode, 20);
8223            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8224            // if Rn == '1111' then SEE MOV (immediate);
8225            if (Rn == 15)
8226                return EmulateMOVRdImm (opcode, eEncodingT2);
8227            if (BadReg(Rd) || Rn == 13)
8228                return false;
8229            break;
8230        case eEncodingA1:
8231            Rd = Bits32(opcode, 15, 12);
8232            Rn = Bits32(opcode, 19, 16);
8233            setflags = BitIsSet(opcode, 20);
8234            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8235            // TODO: Emulate SUBS PC, LR and related instructions.
8236            if (Rd == 15 && setflags)
8237                return false;
8238            break;
8239        default:
8240            return false;
8241        }
8242
8243        // Read the first operand.
8244        uint32_t val1 = ReadCoreReg(Rn, &success);
8245        if (!success)
8246            return false;
8247
8248        uint32_t result = val1 | imm32;
8249
8250        EmulateInstruction::Context context;
8251        context.type = EmulateInstruction::eContextImmediate;
8252        context.SetNoArgs ();
8253
8254        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8255            return false;
8256    }
8257    return true;
8258}
8259
8260// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8261// value, and writes the result to the destination register.  It can optionally update the condition flags based
8262// on the result.
8263bool
8264EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8265{
8266#if 0
8267    // ARM pseudo code...
8268    if ConditionPassed() then
8269        EncodingSpecificOperations();
8270        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8271        result = R[n] OR shifted;
8272        if d == 15 then         // Can only occur for ARM encoding
8273            ALUWritePC(result); // setflags is always FALSE here
8274        else
8275            R[d] = result;
8276            if setflags then
8277                APSR.N = result<31>;
8278                APSR.Z = IsZeroBit(result);
8279                APSR.C = carry;
8280                // APSR.V unchanged
8281#endif
8282
8283    bool success = false;
8284
8285    if (ConditionPassed(opcode))
8286    {
8287        uint32_t Rd, Rn, Rm;
8288        ARM_ShifterType shift_t;
8289        uint32_t shift_n; // the shift applied to the value read from Rm
8290        bool setflags;
8291        uint32_t carry;
8292        switch (encoding)
8293        {
8294        case eEncodingT1:
8295            Rd = Rn = Bits32(opcode, 2, 0);
8296            Rm = Bits32(opcode, 5, 3);
8297            setflags = !InITBlock();
8298            shift_t = SRType_LSL;
8299            shift_n = 0;
8300            break;
8301        case eEncodingT2:
8302            Rd = Bits32(opcode, 11, 8);
8303            Rn = Bits32(opcode, 19, 16);
8304            Rm = Bits32(opcode, 3, 0);
8305            setflags = BitIsSet(opcode, 20);
8306            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8307            // if Rn == '1111' then SEE MOV (register);
8308            if (Rn == 15)
8309                return EmulateMOVRdRm (opcode, eEncodingT3);
8310            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8311                return false;
8312            break;
8313        case eEncodingA1:
8314            Rd = Bits32(opcode, 15, 12);
8315            Rn = Bits32(opcode, 19, 16);
8316            Rm = Bits32(opcode, 3, 0);
8317            setflags = BitIsSet(opcode, 20);
8318            shift_n = DecodeImmShiftARM(opcode, shift_t);
8319            // TODO: Emulate SUBS PC, LR and related instructions.
8320            if (Rd == 15 && setflags)
8321                return false;
8322            break;
8323        default:
8324            return false;
8325        }
8326
8327        // Read the first operand.
8328        uint32_t val1 = ReadCoreReg(Rn, &success);
8329        if (!success)
8330            return false;
8331
8332        // Read the second operand.
8333        uint32_t val2 = ReadCoreReg(Rm, &success);
8334        if (!success)
8335            return false;
8336
8337        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8338        uint32_t result = val1 | shifted;
8339
8340        EmulateInstruction::Context context;
8341        context.type = EmulateInstruction::eContextImmediate;
8342        context.SetNoArgs ();
8343
8344        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8345            return false;
8346    }
8347    return true;
8348}
8349
8350// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8351// the destination register. It can optionally update the condition flags based on the result.
8352bool
8353EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8354{
8355#if 0
8356    // ARM pseudo code...
8357    if ConditionPassed() then
8358        EncodingSpecificOperations();
8359        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8360        if d == 15 then         // Can only occur for ARM encoding
8361            ALUWritePC(result); // setflags is always FALSE here
8362        else
8363            R[d] = result;
8364            if setflags then
8365                APSR.N = result<31>;
8366                APSR.Z = IsZeroBit(result);
8367                APSR.C = carry;
8368                APSR.V = overflow;
8369#endif
8370
8371    bool success = false;
8372
8373    uint32_t Rd; // the destination register
8374    uint32_t Rn; // the first operand
8375    bool setflags;
8376    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8377    switch (encoding) {
8378    case eEncodingT1:
8379        Rd = Bits32(opcode, 2, 0);
8380        Rn = Bits32(opcode, 5, 3);
8381        setflags = !InITBlock();
8382        imm32 = 0;
8383        break;
8384    case eEncodingT2:
8385        Rd = Bits32(opcode, 11, 8);
8386        Rn = Bits32(opcode, 19, 16);
8387        setflags = BitIsSet(opcode, 20);
8388        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8389        if (BadReg(Rd) || BadReg(Rn))
8390            return false;
8391        break;
8392    case eEncodingA1:
8393        Rd = Bits32(opcode, 15, 12);
8394        Rn = Bits32(opcode, 19, 16);
8395        setflags = BitIsSet(opcode, 20);
8396        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8397        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8398        // TODO: Emulate SUBS PC, LR and related instructions.
8399        if (Rd == 15 && setflags)
8400            return false;
8401        break;
8402    default:
8403        return false;
8404    }
8405    // Read the register value from the operand register Rn.
8406    uint32_t reg_val = ReadCoreReg(Rn, &success);
8407    if (!success)
8408        return false;
8409
8410    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8411
8412    EmulateInstruction::Context context;
8413    context.type = EmulateInstruction::eContextImmediate;
8414    context.SetNoArgs ();
8415
8416    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8417        return false;
8418
8419    return true;
8420}
8421
8422// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8423// result to the destination register. It can optionally update the condition flags based on the result.
8424bool
8425EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8426{
8427#if 0
8428    // ARM pseudo code...
8429    if ConditionPassed() then
8430        EncodingSpecificOperations();
8431        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8432        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8433        if d == 15 then         // Can only occur for ARM encoding
8434            ALUWritePC(result); // setflags is always FALSE here
8435        else
8436            R[d] = result;
8437            if setflags then
8438                APSR.N = result<31>;
8439                APSR.Z = IsZeroBit(result);
8440                APSR.C = carry;
8441                APSR.V = overflow;
8442#endif
8443
8444    bool success = false;
8445
8446    uint32_t Rd; // the destination register
8447    uint32_t Rn; // the first operand
8448    uint32_t Rm; // the second operand
8449    bool setflags;
8450    ARM_ShifterType shift_t;
8451    uint32_t shift_n; // the shift applied to the value read from Rm
8452    switch (encoding) {
8453    case eEncodingT1:
8454        Rd = Bits32(opcode, 11, 8);
8455        Rn = Bits32(opcode, 19, 16);
8456        Rm = Bits32(opcode, 3, 0);
8457        setflags = BitIsSet(opcode, 20);
8458        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8459        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8460        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8461            return false;
8462        break;
8463    case eEncodingA1:
8464        Rd = Bits32(opcode, 15, 12);
8465        Rn = Bits32(opcode, 19, 16);
8466        Rm = Bits32(opcode, 3, 0);
8467        setflags = BitIsSet(opcode, 20);
8468        shift_n = DecodeImmShiftARM(opcode, shift_t);
8469        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8470        // TODO: Emulate SUBS PC, LR and related instructions.
8471        if (Rd == 15 && setflags)
8472            return false;
8473        break;
8474    default:
8475        return false;
8476    }
8477    // Read the register value from register Rn.
8478    uint32_t val1 = ReadCoreReg(Rn, &success);
8479    if (!success)
8480        return false;
8481
8482    // Read the register value from register Rm.
8483    uint32_t val2 = ReadCoreReg(Rm, &success);
8484    if (!success)
8485        return false;
8486
8487    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8488    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8489
8490    EmulateInstruction::Context context;
8491    context.type = EmulateInstruction::eContextImmediate;
8492    context.SetNoArgs();
8493    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8494        return false;
8495
8496    return true;
8497}
8498
8499// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8500// an immediate value, and writes the result to the destination register. It can optionally update the condition
8501// flags based on the result.
8502bool
8503EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8504{
8505#if 0
8506    // ARM pseudo code...
8507    if ConditionPassed() then
8508        EncodingSpecificOperations();
8509        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8510        if d == 15 then
8511            ALUWritePC(result); // setflags is always FALSE here
8512        else
8513            R[d] = result;
8514            if setflags then
8515                APSR.N = result<31>;
8516                APSR.Z = IsZeroBit(result);
8517                APSR.C = carry;
8518                APSR.V = overflow;
8519#endif
8520
8521    bool success = false;
8522
8523    uint32_t Rd; // the destination register
8524    uint32_t Rn; // the first operand
8525    bool setflags;
8526    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8527    switch (encoding) {
8528    case eEncodingA1:
8529        Rd = Bits32(opcode, 15, 12);
8530        Rn = Bits32(opcode, 19, 16);
8531        setflags = BitIsSet(opcode, 20);
8532        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8533        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8534        // TODO: Emulate SUBS PC, LR and related instructions.
8535        if (Rd == 15 && setflags)
8536            return false;
8537        break;
8538    default:
8539        return false;
8540    }
8541    // Read the register value from the operand register Rn.
8542    uint32_t reg_val = ReadCoreReg(Rn, &success);
8543    if (!success)
8544        return false;
8545
8546    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8547
8548    EmulateInstruction::Context context;
8549    context.type = EmulateInstruction::eContextImmediate;
8550    context.SetNoArgs ();
8551
8552    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8553        return false;
8554
8555    return true;
8556}
8557
8558// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8559// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8560// condition flags based on the result.
8561bool
8562EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8563{
8564#if 0
8565    // ARM pseudo code...
8566    if ConditionPassed() then
8567        EncodingSpecificOperations();
8568        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8569        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8570        if d == 15 then
8571            ALUWritePC(result); // setflags is always FALSE here
8572        else
8573            R[d] = result;
8574            if setflags then
8575                APSR.N = result<31>;
8576                APSR.Z = IsZeroBit(result);
8577                APSR.C = carry;
8578                APSR.V = overflow;
8579#endif
8580
8581    bool success = false;
8582
8583    uint32_t Rd; // the destination register
8584    uint32_t Rn; // the first operand
8585    uint32_t Rm; // the second operand
8586    bool setflags;
8587    ARM_ShifterType shift_t;
8588    uint32_t shift_n; // the shift applied to the value read from Rm
8589    switch (encoding) {
8590    case eEncodingA1:
8591        Rd = Bits32(opcode, 15, 12);
8592        Rn = Bits32(opcode, 19, 16);
8593        Rm = Bits32(opcode, 3, 0);
8594        setflags = BitIsSet(opcode, 20);
8595        shift_n = DecodeImmShiftARM(opcode, shift_t);
8596        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8597        // TODO: Emulate SUBS PC, LR and related instructions.
8598        if (Rd == 15 && setflags)
8599            return false;
8600        break;
8601    default:
8602        return false;
8603    }
8604    // Read the register value from register Rn.
8605    uint32_t val1 = ReadCoreReg(Rn, &success);
8606    if (!success)
8607        return false;
8608
8609    // Read the register value from register Rm.
8610    uint32_t val2 = ReadCoreReg(Rm, &success);
8611    if (!success)
8612        return false;
8613
8614    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8615    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8616
8617    EmulateInstruction::Context context;
8618    context.type = EmulateInstruction::eContextImmediate;
8619    context.SetNoArgs();
8620    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8621        return false;
8622
8623    return true;
8624}
8625
8626// Subtract with Carry (immediate) subtracts an immediate value and the value of
8627// NOT (Carry flag) from a register value, and writes the result to the destination register.
8628// It can optionally update the condition flags based on the result.
8629bool
8630EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8631{
8632#if 0
8633    // ARM pseudo code...
8634    if ConditionPassed() then
8635        EncodingSpecificOperations();
8636        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8637        if d == 15 then         // Can only occur for ARM encoding
8638            ALUWritePC(result); // setflags is always FALSE here
8639        else
8640            R[d] = result;
8641            if setflags then
8642                APSR.N = result<31>;
8643                APSR.Z = IsZeroBit(result);
8644                APSR.C = carry;
8645                APSR.V = overflow;
8646#endif
8647
8648    bool success = false;
8649
8650    uint32_t Rd; // the destination register
8651    uint32_t Rn; // the first operand
8652    bool setflags;
8653    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8654    switch (encoding) {
8655    case eEncodingT1:
8656        Rd = Bits32(opcode, 11, 8);
8657        Rn = Bits32(opcode, 19, 16);
8658        setflags = BitIsSet(opcode, 20);
8659        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8660        if (BadReg(Rd) || BadReg(Rn))
8661            return false;
8662        break;
8663    case eEncodingA1:
8664        Rd = Bits32(opcode, 15, 12);
8665        Rn = Bits32(opcode, 19, 16);
8666        setflags = BitIsSet(opcode, 20);
8667        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8668        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8669        // TODO: Emulate SUBS PC, LR and related instructions.
8670        if (Rd == 15 && setflags)
8671            return false;
8672        break;
8673    default:
8674        return false;
8675    }
8676    // Read the register value from the operand register Rn.
8677    uint32_t reg_val = ReadCoreReg(Rn, &success);
8678    if (!success)
8679        return false;
8680
8681    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8682
8683    EmulateInstruction::Context context;
8684    context.type = EmulateInstruction::eContextImmediate;
8685    context.SetNoArgs ();
8686
8687    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8688        return false;
8689
8690    return true;
8691}
8692
8693// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8694// NOT (Carry flag) from a register value, and writes the result to the destination register.
8695// It can optionally update the condition flags based on the result.
8696bool
8697EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8698{
8699#if 0
8700    // ARM pseudo code...
8701    if ConditionPassed() then
8702        EncodingSpecificOperations();
8703        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8704        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8705        if d == 15 then         // Can only occur for ARM encoding
8706            ALUWritePC(result); // setflags is always FALSE here
8707        else
8708            R[d] = result;
8709            if setflags then
8710                APSR.N = result<31>;
8711                APSR.Z = IsZeroBit(result);
8712                APSR.C = carry;
8713                APSR.V = overflow;
8714#endif
8715
8716    bool success = false;
8717
8718    uint32_t Rd; // the destination register
8719    uint32_t Rn; // the first operand
8720    uint32_t Rm; // the second operand
8721    bool setflags;
8722    ARM_ShifterType shift_t;
8723    uint32_t shift_n; // the shift applied to the value read from Rm
8724    switch (encoding) {
8725    case eEncodingT1:
8726        Rd = Rn = Bits32(opcode, 2, 0);
8727        Rm = Bits32(opcode, 5, 3);
8728        setflags = !InITBlock();
8729        shift_t = SRType_LSL;
8730        shift_n = 0;
8731        break;
8732    case eEncodingT2:
8733        Rd = Bits32(opcode, 11, 8);
8734        Rn = Bits32(opcode, 19, 16);
8735        Rm = Bits32(opcode, 3, 0);
8736        setflags = BitIsSet(opcode, 20);
8737        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8738        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8739            return false;
8740        break;
8741    case eEncodingA1:
8742        Rd = Bits32(opcode, 15, 12);
8743        Rn = Bits32(opcode, 19, 16);
8744        Rm = Bits32(opcode, 3, 0);
8745        setflags = BitIsSet(opcode, 20);
8746        shift_n = DecodeImmShiftARM(opcode, shift_t);
8747        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8748        // TODO: Emulate SUBS PC, LR and related instructions.
8749        if (Rd == 15 && setflags)
8750            return false;
8751        break;
8752    default:
8753        return false;
8754    }
8755    // Read the register value from register Rn.
8756    uint32_t val1 = ReadCoreReg(Rn, &success);
8757    if (!success)
8758        return false;
8759
8760    // Read the register value from register Rm.
8761    uint32_t val2 = ReadCoreReg(Rm, &success);
8762    if (!success)
8763        return false;
8764
8765    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8766    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8767
8768    EmulateInstruction::Context context;
8769    context.type = EmulateInstruction::eContextImmediate;
8770    context.SetNoArgs();
8771    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8772        return false;
8773
8774    return true;
8775}
8776
8777// This instruction subtracts an immediate value from a register value, and writes the result
8778// to the destination register.  It can optionally update the condition flags based on the result.
8779bool
8780EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
8781{
8782#if 0
8783    // ARM pseudo code...
8784    if ConditionPassed() then
8785        EncodingSpecificOperations();
8786        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8787        R[d] = result;
8788        if setflags then
8789            APSR.N = result<31>;
8790            APSR.Z = IsZeroBit(result);
8791            APSR.C = carry;
8792            APSR.V = overflow;
8793#endif
8794
8795    bool success = false;
8796
8797    uint32_t Rd; // the destination register
8798    uint32_t Rn; // the first operand
8799    bool setflags;
8800    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8801    switch (encoding) {
8802    case eEncodingT1:
8803        Rd = Bits32(opcode, 2, 0);
8804        Rn = Bits32(opcode, 5, 3);
8805        setflags = !InITBlock();
8806        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
8807        break;
8808    case eEncodingT2:
8809        Rd = Rn = Bits32(opcode, 10, 8);
8810        setflags = !InITBlock();
8811        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
8812        break;
8813    case eEncodingT3:
8814        Rd = Bits32(opcode, 11, 8);
8815        Rn = Bits32(opcode, 19, 16);
8816        setflags = BitIsSet(opcode, 20);
8817        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8818
8819        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
8820        if (Rd == 15 && setflags)
8821            return EmulateCMPImm (opcode, eEncodingT2);
8822
8823        // if Rn == '1101' then SEE SUB (SP minus immediate);
8824        if (Rn == 13)
8825            return EmulateSUBSPImm (opcode, eEncodingT2);
8826
8827        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
8828        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
8829            return false;
8830        break;
8831    case eEncodingT4:
8832        Rd = Bits32(opcode, 11, 8);
8833        Rn = Bits32(opcode, 19, 16);
8834        setflags = BitIsSet(opcode, 20);
8835        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
8836
8837        // if Rn == '1111' then SEE ADR;
8838        if (Rn == 15)
8839            return EmulateADR (opcode, eEncodingT2);
8840
8841        // if Rn == '1101' then SEE SUB (SP minus immediate);
8842        if (Rn == 13)
8843            return EmulateSUBSPImm (opcode, eEncodingT3);
8844
8845        if (BadReg(Rd))
8846            return false;
8847        break;
8848    default:
8849        return false;
8850    }
8851    // Read the register value from the operand register Rn.
8852    uint32_t reg_val = ReadCoreReg(Rn, &success);
8853    if (!success)
8854        return false;
8855
8856    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8857
8858    EmulateInstruction::Context context;
8859    context.type = EmulateInstruction::eContextImmediate;
8860    context.SetNoArgs ();
8861
8862    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8863        return false;
8864
8865    return true;
8866}
8867
8868// This instruction subtracts an immediate value from a register value, and writes the result
8869// to the destination register.  It can optionally update the condition flags based on the result.
8870bool
8871EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
8872{
8873#if 0
8874    // ARM pseudo code...
8875    if ConditionPassed() then
8876        EncodingSpecificOperations();
8877        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8878        if d == 15 then
8879            ALUWritePC(result); // setflags is always FALSE here
8880        else
8881            R[d] = result;
8882            if setflags then
8883                APSR.N = result<31>;
8884                APSR.Z = IsZeroBit(result);
8885                APSR.C = carry;
8886                APSR.V = overflow;
8887#endif
8888
8889    bool success = false;
8890
8891    uint32_t Rd; // the destination register
8892    uint32_t Rn; // the first operand
8893    bool setflags;
8894    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8895    switch (encoding) {
8896    case eEncodingA1:
8897        Rd = Bits32(opcode, 15, 12);
8898        Rn = Bits32(opcode, 19, 16);
8899        setflags = BitIsSet(opcode, 20);
8900        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8901
8902        // if Rn == '1111' && S == '0' then SEE ADR;
8903        if (Rn == 15 && !setflags)
8904            return EmulateADR (opcode, eEncodingA2);
8905
8906        // if Rn == '1101' then SEE SUB (SP minus immediate);
8907        if (Rn == 13)
8908            return EmulateSUBSPImm (opcode, eEncodingA1);
8909
8910        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8911        // TODO: Emulate SUBS PC, LR and related instructions.
8912        if (Rd == 15 && setflags)
8913            return false;
8914        break;
8915    default:
8916        return false;
8917    }
8918    // Read the register value from the operand register Rn.
8919    uint32_t reg_val = ReadCoreReg(Rn, &success);
8920    if (!success)
8921        return false;
8922
8923    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8924
8925    EmulateInstruction::Context context;
8926    context.type = EmulateInstruction::eContextImmediate;
8927    context.SetNoArgs ();
8928
8929    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8930        return false;
8931
8932    return true;
8933}
8934
8935// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
8936// immediate value.  It updates the condition flags based on the result, and discards the result.
8937bool
8938EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
8939{
8940#if 0
8941    // ARM pseudo code...
8942    if ConditionPassed() then
8943        EncodingSpecificOperations();
8944        result = R[n] EOR imm32;
8945        APSR.N = result<31>;
8946        APSR.Z = IsZeroBit(result);
8947        APSR.C = carry;
8948        // APSR.V unchanged
8949#endif
8950
8951    bool success = false;
8952
8953    if (ConditionPassed(opcode))
8954    {
8955        uint32_t Rn;
8956        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
8957        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8958        switch (encoding)
8959        {
8960        case eEncodingT1:
8961            Rn = Bits32(opcode, 19, 16);
8962            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8963            if (BadReg(Rn))
8964                return false;
8965            break;
8966        case eEncodingA1:
8967            Rn = Bits32(opcode, 19, 16);
8968            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8969            break;
8970        default:
8971            return false;
8972        }
8973
8974        // Read the first operand.
8975        uint32_t val1 = ReadCoreReg(Rn, &success);
8976        if (!success)
8977            return false;
8978
8979        uint32_t result = val1 ^ imm32;
8980
8981        EmulateInstruction::Context context;
8982        context.type = EmulateInstruction::eContextImmediate;
8983        context.SetNoArgs ();
8984
8985        if (!WriteFlags(context, result, carry))
8986            return false;
8987    }
8988    return true;
8989}
8990
8991// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
8992// optionally-shifted register value.  It updates the condition flags based on the result, and discards
8993// the result.
8994bool
8995EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
8996{
8997#if 0
8998    // ARM pseudo code...
8999    if ConditionPassed() then
9000        EncodingSpecificOperations();
9001        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9002        result = R[n] EOR shifted;
9003        APSR.N = result<31>;
9004        APSR.Z = IsZeroBit(result);
9005        APSR.C = carry;
9006        // APSR.V unchanged
9007#endif
9008
9009    bool success = false;
9010
9011    if (ConditionPassed(opcode))
9012    {
9013        uint32_t Rn, Rm;
9014        ARM_ShifterType shift_t;
9015        uint32_t shift_n; // the shift applied to the value read from Rm
9016        uint32_t carry;
9017        switch (encoding)
9018        {
9019        case eEncodingT1:
9020            Rn = Bits32(opcode, 19, 16);
9021            Rm = Bits32(opcode, 3, 0);
9022            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9023            if (BadReg(Rn) || BadReg(Rm))
9024                return false;
9025            break;
9026        case eEncodingA1:
9027            Rn = Bits32(opcode, 19, 16);
9028            Rm = Bits32(opcode, 3, 0);
9029            shift_n = DecodeImmShiftARM(opcode, shift_t);
9030            break;
9031        default:
9032            return false;
9033        }
9034
9035        // Read the first operand.
9036        uint32_t val1 = ReadCoreReg(Rn, &success);
9037        if (!success)
9038            return false;
9039
9040        // Read the second operand.
9041        uint32_t val2 = ReadCoreReg(Rm, &success);
9042        if (!success)
9043            return false;
9044
9045        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9046        uint32_t result = val1 ^ shifted;
9047
9048        EmulateInstruction::Context context;
9049        context.type = EmulateInstruction::eContextImmediate;
9050        context.SetNoArgs ();
9051
9052        if (!WriteFlags(context, result, carry))
9053            return false;
9054    }
9055    return true;
9056}
9057
9058// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9059// It updates the condition flags based on the result, and discards the result.
9060bool
9061EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9062{
9063#if 0
9064    // ARM pseudo code...
9065    if ConditionPassed() then
9066        EncodingSpecificOperations();
9067        result = R[n] AND imm32;
9068        APSR.N = result<31>;
9069        APSR.Z = IsZeroBit(result);
9070        APSR.C = carry;
9071        // APSR.V unchanged
9072#endif
9073
9074    bool success = false;
9075
9076    if (ConditionPassed(opcode))
9077    {
9078        uint32_t Rn;
9079        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9080        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9081        switch (encoding)
9082        {
9083        case eEncodingT1:
9084            Rn = Bits32(opcode, 19, 16);
9085            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9086            if (BadReg(Rn))
9087                return false;
9088            break;
9089        case eEncodingA1:
9090            Rn = Bits32(opcode, 19, 16);
9091            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
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        uint32_t result = val1 & imm32;
9103
9104        EmulateInstruction::Context context;
9105        context.type = EmulateInstruction::eContextImmediate;
9106        context.SetNoArgs ();
9107
9108        if (!WriteFlags(context, result, carry))
9109            return false;
9110    }
9111    return true;
9112}
9113
9114// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9115// It updates the condition flags based on the result, and discards the result.
9116bool
9117EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9118{
9119#if 0
9120    // ARM pseudo code...
9121    if ConditionPassed() then
9122        EncodingSpecificOperations();
9123        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9124        result = R[n] AND shifted;
9125        APSR.N = result<31>;
9126        APSR.Z = IsZeroBit(result);
9127        APSR.C = carry;
9128        // APSR.V unchanged
9129#endif
9130
9131    bool success = false;
9132
9133    if (ConditionPassed(opcode))
9134    {
9135        uint32_t Rn, Rm;
9136        ARM_ShifterType shift_t;
9137        uint32_t shift_n; // the shift applied to the value read from Rm
9138        uint32_t carry;
9139        switch (encoding)
9140        {
9141        case eEncodingT1:
9142            Rn = Bits32(opcode, 2, 0);
9143            Rm = Bits32(opcode, 5, 3);
9144            shift_t = SRType_LSL;
9145            shift_n = 0;
9146            break;
9147        case eEncodingT2:
9148            Rn = Bits32(opcode, 19, 16);
9149            Rm = Bits32(opcode, 3, 0);
9150            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9151            if (BadReg(Rn) || BadReg(Rm))
9152                return false;
9153            break;
9154        case eEncodingA1:
9155            Rn = Bits32(opcode, 19, 16);
9156            Rm = Bits32(opcode, 3, 0);
9157            shift_n = DecodeImmShiftARM(opcode, shift_t);
9158            break;
9159        default:
9160            return false;
9161        }
9162
9163        // Read the first operand.
9164        uint32_t val1 = ReadCoreReg(Rn, &success);
9165        if (!success)
9166            return false;
9167
9168        // Read the second operand.
9169        uint32_t val2 = ReadCoreReg(Rm, &success);
9170        if (!success)
9171            return false;
9172
9173        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9174        uint32_t result = val1 & shifted;
9175
9176        EmulateInstruction::Context context;
9177        context.type = EmulateInstruction::eContextImmediate;
9178        context.SetNoArgs ();
9179
9180        if (!WriteFlags(context, result, carry))
9181            return false;
9182    }
9183    return true;
9184}
9185
9186// A8.6.216 SUB (SP minus register)
9187bool
9188EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9189{
9190#if 0
9191    if ConditionPassed() then
9192        EncodingSpecificOperations();
9193        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9194        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9195        if d == 15 then // Can only occur for ARM encoding
9196            ALUWritePC(result); // setflags is always FALSE here
9197        else
9198            R[d] = result;
9199            if setflags then
9200                APSR.N = result<31>;
9201                APSR.Z = IsZeroBit(result);
9202                APSR.C = carry;
9203                APSR.V = overflow;
9204#endif
9205
9206    bool success = false;
9207
9208    if (ConditionPassed(opcode))
9209    {
9210        uint32_t d;
9211        uint32_t m;
9212        bool setflags;
9213        ARM_ShifterType shift_t;
9214        uint32_t shift_n;
9215
9216        switch (encoding)
9217        {
9218            case eEncodingT1:
9219                // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9220                d = Bits32 (opcode, 11, 8);
9221                m = Bits32 (opcode, 3, 0);
9222                setflags = BitIsSet (opcode, 20);
9223
9224                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9225                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9226
9227                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9228                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9229                    return false;
9230
9231                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9232                if ((d == 15) || BadReg (m))
9233                    return false;
9234                break;
9235
9236            case eEncodingA1:
9237                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9238                // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9239                d = Bits32 (opcode, 15, 12);
9240                m = Bits32 (opcode, 3, 0);
9241                setflags = BitIsSet (opcode, 20);
9242
9243                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9244                shift_n = DecodeImmShiftARM (opcode, shift_t);
9245                break;
9246
9247            default:
9248                return false;
9249        }
9250
9251        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9252        uint32_t Rm = ReadCoreReg (m, &success);
9253        if (!success)
9254            return false;
9255
9256        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9257
9258        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9259        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9260        if (!success)
9261            return false;
9262
9263        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9264
9265        EmulateInstruction::Context context;
9266        context.type = eContextSubtraction;
9267        Register sp_reg;
9268        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
9269        Register dwarf_reg;
9270        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9271        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9272
9273        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9274            return false;
9275    }
9276    return true;
9277}
9278
9279
9280// A8.6.7 ADD (register-shifted register)
9281bool
9282EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9283{
9284#if 0
9285    if ConditionPassed() then
9286        EncodingSpecificOperations();
9287        shift_n = UInt(R[s]<7:0>);
9288        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9289        (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9290        R[d] = result;
9291        if setflags then
9292            APSR.N = result<31>;
9293            APSR.Z = IsZeroBit(result);
9294            APSR.C = carry;
9295            APSR.V = overflow;
9296#endif
9297
9298    bool success = false;
9299
9300    if (ConditionPassed(opcode))
9301    {
9302        uint32_t d;
9303        uint32_t n;
9304        uint32_t m;
9305        uint32_t s;
9306        bool setflags;
9307        ARM_ShifterType shift_t;
9308
9309        switch (encoding)
9310        {
9311            case eEncodingA1:
9312                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9313                d = Bits32 (opcode, 15, 12);
9314                n = Bits32 (opcode, 19, 16);
9315                m = Bits32 (opcode, 3, 0);
9316                s = Bits32 (opcode, 11, 8);
9317
9318                // setflags = (S == ‘1’); shift_t = DecodeRegShift(type);
9319                setflags = BitIsSet (opcode, 20);
9320                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9321
9322                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9323                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9324                    return false;
9325                break;
9326
9327            default:
9328                return false;
9329        }
9330
9331        // shift_n = UInt(R[s]<7:0>);
9332        uint32_t Rs = ReadCoreReg (s, &success);
9333        if (!success)
9334            return false;
9335
9336        uint32_t shift_n = Bits32 (Rs, 7, 0);
9337
9338        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9339        uint32_t Rm = ReadCoreReg (m, &success);
9340        if (!success)
9341            return false;
9342
9343        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9344
9345        // (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9346        uint32_t Rn = ReadCoreReg (n, &success);
9347        if (!success)
9348            return false;
9349
9350        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9351
9352        // R[d] = result;
9353        EmulateInstruction::Context context;
9354        context.type = eContextAddition;
9355        Register reg_n;
9356        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
9357        Register reg_m;
9358        reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9359
9360        context.SetRegisterRegisterOperands (reg_n, reg_m);
9361
9362        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9363            return false;
9364
9365        // if setflags then
9366            // APSR.N = result<31>;
9367            // APSR.Z = IsZeroBit(result);
9368            // APSR.C = carry;
9369            // APSR.V = overflow;
9370        if (setflags)
9371            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9372    }
9373    return true;
9374}
9375
9376// A8.6.213 SUB (register)
9377bool
9378EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9379{
9380#if 0
9381    if ConditionPassed() then
9382        EncodingSpecificOperations();
9383        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9384        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9385        if d == 15 then // Can only occur for ARM encoding
9386            ALUWritePC(result); // setflags is always FALSE here
9387        else
9388            R[d] = result;
9389            if setflags then
9390                APSR.N = result<31>;
9391                APSR.Z = IsZeroBit(result);
9392                APSR.C = carry;
9393                APSR.V = overflow;
9394#endif
9395
9396    bool success = false;
9397
9398    if (ConditionPassed(opcode))
9399    {
9400        uint32_t d;
9401        uint32_t n;
9402        uint32_t m;
9403        bool setflags;
9404        ARM_ShifterType shift_t;
9405        uint32_t shift_n;
9406
9407        switch (encoding)
9408        {
9409            case eEncodingT1:
9410                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9411                d = Bits32 (opcode, 2, 0);
9412                n = Bits32 (opcode, 5, 3);
9413                m = Bits32 (opcode, 8, 6);
9414                setflags = !InITBlock();
9415
9416                // (shift_t, shift_n) = (SRType_LSL, 0);
9417                shift_t = SRType_LSL;
9418                shift_n = 0;
9419
9420                break;
9421
9422            case eEncodingT2:
9423                // if Rd == ‘1111’ && S == ‘1’ then SEE CMP (register);
9424                // if Rn == ‘1101’ then SEE SUB (SP minus register);
9425                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9426                d = Bits32 (opcode, 11, 8);
9427                n = Bits32 (opcode, 19, 16);
9428                m = Bits32 (opcode, 3, 0);
9429                setflags = BitIsSet (opcode, 20);
9430
9431                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9432                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9433
9434                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9435                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9436                    return false;
9437
9438                break;
9439
9440            case eEncodingA1:
9441                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9442                // if Rn == ‘1101’ then SEE SUB (SP minus register);
9443                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9444                d = Bits32 (opcode, 15, 12);
9445                n = Bits32 (opcode, 19, 16);
9446                m = Bits32 (opcode, 3, 0);
9447                setflags = BitIsSet (opcode, 20);
9448
9449                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9450                shift_n = DecodeImmShiftARM (opcode, shift_t);
9451
9452                break;
9453
9454            default:
9455                return false;
9456        }
9457
9458        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9459        uint32_t Rm = ReadCoreReg (m, &success);
9460        if (!success)
9461            return false;
9462
9463        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9464
9465        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9466        uint32_t Rn = ReadCoreReg (n, &success);
9467        if (!success)
9468            return false;
9469
9470        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9471
9472        // if d == 15 then // Can only occur for ARM encoding
9473            // ALUWritePC(result); // setflags is always FALSE here
9474        // else
9475            // R[d] = result;
9476            // if setflags then
9477                // APSR.N = result<31>;
9478                // APSR.Z = IsZeroBit(result);
9479                // APSR.C = carry;
9480                // APSR.V = overflow;
9481
9482        EmulateInstruction::Context context;
9483        context.type = eContextSubtraction;
9484        Register reg_n;
9485        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9486        Register reg_m;
9487        reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9488        context.SetRegisterRegisterOperands (reg_n, reg_m);
9489
9490        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9491            return false;
9492    }
9493    return true;
9494}
9495
9496// A8.6.202 STREX
9497// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9498// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9499bool
9500EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9501{
9502#if 0
9503    if ConditionPassed() then
9504        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9505        address = R[n] + imm32;
9506        if ExclusiveMonitorsPass(address,4) then
9507            MemA[address,4] = R[t];
9508            R[d] = 0;
9509        else
9510            R[d] = 1;
9511#endif
9512
9513    bool success = false;
9514
9515    if (ConditionPassed(opcode))
9516    {
9517        uint32_t d;
9518        uint32_t t;
9519        uint32_t n;
9520        uint32_t imm32;
9521        const uint32_t addr_byte_size = GetAddressByteSize();
9522
9523        switch (encoding)
9524        {
9525            case eEncodingT1:
9526                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9527                d = Bits32 (opcode, 11, 8);
9528                t = Bits32 (opcode, 15, 12);
9529                n = Bits32 (opcode, 19, 16);
9530                imm32 = Bits32 (opcode, 7, 0) << 2;
9531
9532                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9533                if (BadReg (d) || BadReg (t) || (n == 15))
9534                  return false;
9535
9536                // if d == n || d == t then UNPREDICTABLE;
9537                if ((d == n) || (d == t))
9538                  return false;
9539
9540                break;
9541
9542            case eEncodingA1:
9543                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9544                d = Bits32 (opcode, 15, 12);
9545                t = Bits32 (opcode, 3, 0);
9546                n = Bits32 (opcode, 19, 16);
9547                imm32 = 0;
9548
9549                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9550                if ((d == 15) || (t == 15) || (n == 15))
9551                    return false;
9552
9553                // if d == n || d == t then UNPREDICTABLE;
9554                if ((d == n) || (d == t))
9555                    return false;
9556
9557                break;
9558
9559            default:
9560                return false;
9561        }
9562
9563        // address = R[n] + imm32;
9564        uint32_t Rn = ReadCoreReg (n, &success);
9565        if (!success)
9566            return false;
9567
9568        addr_t address = Rn + imm32;
9569
9570        Register base_reg;
9571        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9572        Register data_reg;
9573        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9574        EmulateInstruction::Context context;
9575        context.type = eContextRegisterStore;
9576        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9577
9578        // if ExclusiveMonitorsPass(address,4) then
9579        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9580        //                                                         always return true.
9581        if (true)
9582        {
9583            // MemA[address,4] = R[t];
9584            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9585            if (!success)
9586                return false;
9587
9588            if (!MemAWrite (context, address, Rt, addr_byte_size))
9589                return false;
9590
9591            // R[d] = 0;
9592            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9593                return false;
9594        }
9595        else
9596        {
9597            // R[d] = 1;
9598            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9599                return false;
9600        }
9601    }
9602    return true;
9603}
9604
9605// A8.6.197 STRB (immediate, ARM)
9606bool
9607EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9608{
9609#if 0
9610    if ConditionPassed() then
9611        EncodingSpecificOperations();
9612        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9613        address = if index then offset_addr else R[n];
9614        MemU[address,1] = R[t]<7:0>;
9615        if wback then R[n] = offset_addr;
9616#endif
9617
9618    bool success = false;
9619
9620    if (ConditionPassed(opcode))
9621    {
9622        uint32_t t;
9623        uint32_t n;
9624        uint32_t imm32;
9625        bool index;
9626        bool add;
9627        bool wback;
9628
9629        switch (encoding)
9630        {
9631            case eEncodingA1:
9632                // if P == ‘0’ && W == ‘1’ then SEE STRBT;
9633                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9634                t = Bits32 (opcode, 15, 12);
9635                n = Bits32 (opcode, 19, 16);
9636                imm32 = Bits32 (opcode, 11, 0);
9637
9638                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9639                index = BitIsSet (opcode, 24);
9640                add = BitIsSet (opcode, 23);
9641                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9642
9643                // if t == 15 then UNPREDICTABLE;
9644                if (t == 15)
9645                    return false;
9646
9647                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9648                if (wback && ((n == 15) || (n == t)))
9649                    return false;
9650
9651                break;
9652
9653            default:
9654                return false;
9655        }
9656
9657        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9658        uint32_t Rn = ReadCoreReg (n, &success);
9659        if (!success)
9660            return false;
9661
9662        addr_t offset_addr;
9663        if (add)
9664            offset_addr = Rn + imm32;
9665        else
9666            offset_addr = Rn - imm32;
9667
9668        // address = if index then offset_addr else R[n];
9669        addr_t address;
9670        if (index)
9671            address = offset_addr;
9672        else
9673            address = Rn;
9674
9675        // MemU[address,1] = R[t]<7:0>;
9676        uint32_t Rt = ReadCoreReg (t, &success);
9677        if (!success)
9678            return false;
9679
9680        Register base_reg;
9681        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9682        Register data_reg;
9683        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9684        EmulateInstruction::Context context;
9685        context.type = eContextRegisterStore;
9686        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9687
9688        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9689            return false;
9690
9691        // if wback then R[n] = offset_addr;
9692        if (wback)
9693        {
9694            if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9695                return false;
9696        }
9697    }
9698    return true;
9699}
9700
9701// A8.6.194 STR (immediate, ARM)
9702bool
9703EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9704{
9705#if 0
9706    if ConditionPassed() then
9707        EncodingSpecificOperations();
9708        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9709        address = if index then offset_addr else R[n];
9710        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9711        if wback then R[n] = offset_addr;
9712#endif
9713
9714    bool success = false;
9715
9716    if (ConditionPassed(opcode))
9717    {
9718        uint32_t t;
9719        uint32_t n;
9720        uint32_t imm32;
9721        bool index;
9722        bool add;
9723        bool wback;
9724
9725        const uint32_t addr_byte_size = GetAddressByteSize();
9726
9727        switch (encoding)
9728        {
9729            case eEncodingA1:
9730                // if P == ‘0’ && W == ‘1’ then SEE STRT;
9731                // if Rn == ‘1101’ && P == ‘1’ && U == ‘0’ && W == ‘1’ && imm12 == ‘000000000100’ then SEE PUSH;
9732                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9733                t = Bits32 (opcode, 15, 12);
9734                n = Bits32 (opcode, 19, 16);
9735                imm32 = Bits32 (opcode, 11, 0);
9736
9737                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9738                index = BitIsSet (opcode, 24);
9739                add = BitIsSet (opcode, 23);
9740                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9741
9742                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9743                if (wback && ((n == 15) || (n == t)))
9744                    return false;
9745
9746                break;
9747
9748            default:
9749                return false;
9750        }
9751
9752        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9753        uint32_t Rn = ReadCoreReg (n, &success);
9754        if (!success)
9755            return false;
9756
9757        addr_t offset_addr;
9758        if (add)
9759            offset_addr = Rn + imm32;
9760        else
9761            offset_addr = Rn - imm32;
9762
9763        // address = if index then offset_addr else R[n];
9764        addr_t address;
9765        if (index)
9766            address = offset_addr;
9767        else
9768            address = Rn;
9769
9770        Register base_reg;
9771        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9772        Register data_reg;
9773        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9774        EmulateInstruction::Context context;
9775        context.type = eContextRegisterStore;
9776        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9777
9778        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9779        uint32_t Rt = ReadCoreReg (t, &success);
9780        if (!success)
9781            return false;
9782
9783        if (t == 15)
9784        {
9785            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
9786            if (!success)
9787                return false;
9788
9789            if (!MemUWrite (context, address, pc_value, addr_byte_size))
9790                return false;
9791        }
9792        else
9793        {
9794            if (!MemUWrite (context, address, Rt, addr_byte_size))
9795                  return false;
9796        }
9797
9798        // if wback then R[n] = offset_addr;
9799        if (wback)
9800        {
9801            context.type = eContextAdjustBaseRegister;
9802            context.SetImmediate (offset_addr);
9803
9804            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9805                return false;
9806        }
9807    }
9808    return true;
9809}
9810
9811// A8.6.66 LDRD (immediate)
9812// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
9813// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
9814bool
9815EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
9816{
9817#if 0
9818    if ConditionPassed() then
9819        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9820        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9821        address = if index then offset_addr else R[n];
9822        R[t] = MemA[address,4];
9823        R[t2] = MemA[address+4,4];
9824        if wback then R[n] = offset_addr;
9825#endif
9826
9827    bool success = false;
9828
9829    if (ConditionPassed(opcode))
9830    {
9831        uint32_t t;
9832        uint32_t t2;
9833        uint32_t n;
9834        uint32_t imm32;
9835        bool index;
9836        bool add;
9837        bool wback;
9838
9839        switch (encoding)
9840        {
9841            case eEncodingT1:
9842                //if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
9843                //if Rn == ‘1111’ then SEE LDRD (literal);
9844                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9845                t = Bits32 (opcode, 15, 12);
9846                t2 = Bits32 (opcode, 11, 8);
9847                n = Bits32 (opcode, 19, 16);
9848                imm32 = Bits32 (opcode, 7, 0) << 2;
9849
9850                //index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
9851                index = BitIsSet (opcode, 24);
9852                add = BitIsSet (opcode, 23);
9853                wback = BitIsSet (opcode, 21);
9854
9855                //if wback && (n == t || n == t2) then UNPREDICTABLE;
9856                if (wback && ((n == t) || (n == t2)))
9857                    return false;
9858
9859                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
9860                if (BadReg (t) || BadReg (t2) || (t == t2))
9861                    return false;
9862
9863                break;
9864
9865            case eEncodingA1:
9866                //if Rn == ‘1111’ then SEE LDRD (literal);
9867                //if Rt<0> == ‘1’ then UNPREDICTABLE;
9868                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
9869                t = Bits32 (opcode, 15, 12);
9870                if (BitIsSet (t, 0))
9871                    return false;
9872                t2 = t + 1;
9873                n = Bits32 (opcode, 19, 16);
9874                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
9875
9876                //index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9877                index = BitIsSet (opcode, 24);
9878                add = BitIsSet (opcode, 23);
9879                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9880
9881                //if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
9882                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
9883                    return false;
9884
9885                //if wback && (n == t || n == t2) then UNPREDICTABLE;
9886                if (wback && ((n == t) || (n == t2)))
9887                    return false;
9888
9889                //if t2 == 15 then UNPREDICTABLE;
9890                if (t2 == 15)
9891                    return false;
9892
9893                break;
9894
9895            default:
9896                return false;
9897        }
9898
9899        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9900        uint32_t Rn = ReadCoreReg (n, &success);
9901        if (!success)
9902            return false;
9903
9904        addr_t offset_addr;
9905        if (add)
9906                  offset_addr = Rn + imm32;
9907        else
9908            offset_addr = Rn - imm32;
9909
9910        //address = if index then offset_addr else R[n];
9911        addr_t address;
9912        if (index)
9913            address = offset_addr;
9914        else
9915            address = Rn;
9916
9917        //R[t] = MemA[address,4];
9918        Register base_reg;
9919        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9920
9921        EmulateInstruction::Context context;
9922        context.type = eContextRegisterLoad;
9923        context.SetRegisterPlusOffset (base_reg, address - Rn);
9924
9925        const uint32_t addr_byte_size = GetAddressByteSize();
9926        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
9927        if (!success)
9928            return false;
9929
9930        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
9931            return false;
9932
9933        //R[t2] = MemA[address+4,4];
9934
9935        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
9936        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
9937        if (!success)
9938            return false;
9939
9940        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
9941            return false;
9942
9943        //if wback then R[n] = offset_addr;
9944        if (wback)
9945        {
9946            context.type = eContextAdjustBaseRegister;
9947            context.SetAddress (offset_addr);
9948
9949            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9950                return false;
9951        }
9952    }
9953    return true;
9954}
9955
9956// A8.6.68 LDRD (register)
9957// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
9958// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
9959bool
9960EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
9961{
9962#if 0
9963    if ConditionPassed() then
9964        EncodingSpecificOperations();
9965        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
9966        address = if index then offset_addr else R[n];
9967        R[t] = MemA[address,4];
9968        R[t2] = MemA[address+4,4];
9969        if wback then R[n] = offset_addr;
9970#endif
9971
9972    bool success = false;
9973
9974    if (ConditionPassed(opcode))
9975    {
9976        uint32_t t;
9977        uint32_t t2;
9978        uint32_t n;
9979        uint32_t m;
9980        bool index;
9981        bool add;
9982        bool wback;
9983
9984        switch (encoding)
9985        {
9986            case eEncodingA1:
9987                // if Rt<0> == ‘1’ then UNPREDICTABLE;
9988                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
9989                t = Bits32 (opcode, 15, 12);
9990                if (BitIsSet (t, 0))
9991                    return false;
9992                t2 = t + 1;
9993                n = Bits32 (opcode, 19, 16);
9994                m = Bits32 (opcode, 3, 0);
9995
9996                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9997                index = BitIsSet (opcode, 24);
9998                add = BitIsSet (opcode, 23);
9999                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10000
10001                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10002                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10003                  return false;
10004
10005                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10006                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10007                  return false;
10008
10009                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10010                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10011                  return false;
10012
10013                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10014                if ((ArchVersion() < 6) && wback && (m == n))
10015                  return false;
10016                break;
10017
10018            default:
10019                return false;
10020        }
10021
10022        uint32_t Rn = ReadCoreReg (n, &success);
10023        if (!success)
10024            return false;
10025        Register base_reg;
10026        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10027
10028        uint32_t Rm = ReadCoreReg (m, &success);
10029        if (!success)
10030            return false;
10031        Register offset_reg;
10032        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10033
10034        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10035        addr_t offset_addr;
10036        if (add)
10037            offset_addr = Rn + Rm;
10038        else
10039            offset_addr = Rn - Rm;
10040
10041        // address = if index then offset_addr else R[n];
10042        addr_t address;
10043        if (index)
10044            address = offset_addr;
10045        else
10046            address = Rn;
10047
10048        EmulateInstruction::Context context;
10049        context.type = eContextRegisterLoad;
10050        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10051
10052        // R[t] = MemA[address,4];
10053        const uint32_t addr_byte_size = GetAddressByteSize();
10054        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10055        if (!success)
10056            return false;
10057
10058        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10059            return false;
10060
10061        // R[t2] = MemA[address+4,4];
10062
10063        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10064        if (!success)
10065            return false;
10066
10067        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10068            return false;
10069
10070        // if wback then R[n] = offset_addr;
10071        if (wback)
10072        {
10073            context.type = eContextAdjustBaseRegister;
10074            context.SetAddress (offset_addr);
10075
10076            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10077                return false;
10078        }
10079    }
10080    return true;
10081}
10082
10083// A8.6.200 STRD (immediate)
10084// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10085// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10086bool
10087EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10088{
10089#if 0
10090    if ConditionPassed() then
10091        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10092        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10093        address = if index then offset_addr else R[n];
10094        MemA[address,4] = R[t];
10095        MemA[address+4,4] = R[t2];
10096        if wback then R[n] = offset_addr;
10097#endif
10098
10099    bool success = false;
10100
10101    if (ConditionPassed(opcode))
10102    {
10103        uint32_t t;
10104        uint32_t t2;
10105        uint32_t n;
10106        uint32_t imm32;
10107        bool index;
10108        bool add;
10109        bool wback;
10110
10111        switch (encoding)
10112        {
10113            case eEncodingT1:
10114                // if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10115                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10116                t = Bits32 (opcode, 15, 12);
10117                t2 = Bits32 (opcode, 11, 8);
10118                n = Bits32 (opcode, 19, 16);
10119                imm32 = Bits32 (opcode, 7, 0) << 2;
10120
10121                // index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
10122                index = BitIsSet (opcode, 24);
10123                add = BitIsSet (opcode, 23);
10124                wback = BitIsSet (opcode, 21);
10125
10126                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10127                if (wback && ((n == t) || (n == t2)))
10128                    return false;
10129
10130                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10131                if ((n == 15) || BadReg (t) || BadReg (t2))
10132                    return false;
10133
10134                break;
10135
10136            case eEncodingA1:
10137                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10138                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10139                t = Bits32 (opcode, 15, 12);
10140                if (BitIsSet (t, 0))
10141                    return false;
10142
10143                t2 = t + 1;
10144                n = Bits32 (opcode, 19, 16);
10145                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10146
10147                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10148                index = BitIsSet (opcode, 24);
10149                add = BitIsSet (opcode, 23);
10150                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10151
10152                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10153                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10154                    return false;
10155
10156                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10157                if (wback && ((n == 15) || (n == t) || (n == t2)))
10158                    return false;
10159
10160                // if t2 == 15 then UNPREDICTABLE;
10161                if (t2 == 15)
10162                    return false;
10163
10164                break;
10165
10166            default:
10167                return false;
10168        }
10169
10170        Register base_reg;
10171        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10172
10173        uint32_t Rn = ReadCoreReg (n, &success);
10174        if (!success)
10175            return false;
10176
10177        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10178        addr_t offset_addr;
10179        if (add)
10180            offset_addr = Rn + imm32;
10181        else
10182            offset_addr = Rn - imm32;
10183
10184        //address = if index then offset_addr else R[n];
10185        addr_t address;
10186        if (index)
10187            address = offset_addr;
10188        else
10189            address = Rn;
10190
10191        //MemA[address,4] = R[t];
10192        Register data_reg;
10193        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10194
10195        uint32_t data = ReadCoreReg (t, &success);
10196        if (!success)
10197            return false;
10198
10199        EmulateInstruction::Context context;
10200        context.type = eContextRegisterStore;
10201        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10202
10203        const uint32_t addr_byte_size = GetAddressByteSize();
10204
10205        if (!MemAWrite (context, address, data, addr_byte_size))
10206            return false;
10207
10208        //MemA[address+4,4] = R[t2];
10209        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t2);
10210        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10211
10212        data = ReadCoreReg (t2, &success);
10213        if (!success)
10214            return false;
10215
10216        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10217            return false;
10218
10219        //if wback then R[n] = offset_addr;
10220        if (wback)
10221        {
10222            context.type = eContextAdjustBaseRegister;
10223            context.SetAddress (offset_addr);
10224
10225            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10226                return false;
10227        }
10228    }
10229    return true;
10230}
10231
10232
10233// A8.6.201 STRD (register)
10234bool
10235EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10236{
10237#if 0
10238    if ConditionPassed() then
10239        EncodingSpecificOperations();
10240        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10241        address = if index then offset_addr else R[n];
10242        MemA[address,4] = R[t];
10243        MemA[address+4,4] = R[t2];
10244        if wback then R[n] = offset_addr;
10245#endif
10246
10247    bool success = false;
10248
10249    if (ConditionPassed(opcode))
10250    {
10251        uint32_t t;
10252        uint32_t t2;
10253        uint32_t n;
10254        uint32_t m;
10255        bool index;
10256        bool add;
10257        bool wback;
10258
10259        switch (encoding)
10260        {
10261            case eEncodingA1:
10262                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10263                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10264                t = Bits32 (opcode, 15, 12);
10265                if (BitIsSet (t, 0))
10266                   return false;
10267
10268                t2 = t+1;
10269                n = Bits32 (opcode, 19, 16);
10270                m = Bits32 (opcode, 3, 0);
10271
10272                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10273                index = BitIsSet (opcode, 24);
10274                add = BitIsSet (opcode, 23);
10275                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10276
10277                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10278                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10279                   return false;
10280
10281                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10282                if ((t2 == 15) || (m == 15))
10283                   return false;
10284
10285                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10286                if (wback && ((n == 15) || (n == t) || (n == t2)))
10287                   return false;
10288
10289                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10290                if ((ArchVersion() < 6) && wback && (m == n))
10291                   return false;
10292
10293                break;
10294
10295            default:
10296                return false;
10297        }
10298
10299        Register base_reg;
10300        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10301        Register offset_reg;
10302        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10303        Register data_reg;
10304        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10305
10306        uint32_t Rn = ReadCoreReg (n, &success);
10307        if (!success)
10308            return false;
10309
10310        uint32_t Rm = ReadCoreReg (m, &success);
10311        if (!success)
10312            return false;
10313
10314        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10315        addr_t offset_addr;
10316        if (add)
10317            offset_addr = Rn + Rm;
10318        else
10319            offset_addr = Rn - Rm;
10320
10321        // address = if index then offset_addr else R[n];
10322        addr_t address;
10323        if (index)
10324            address = offset_addr;
10325        else
10326            address = Rn;
10327                          // MemA[address,4] = R[t];
10328        uint32_t Rt = ReadCoreReg (t, &success);
10329        if (!success)
10330            return false;
10331
10332        EmulateInstruction::Context context;
10333        context.type = eContextRegisterStore;
10334        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10335
10336        const uint32_t addr_byte_size = GetAddressByteSize();
10337
10338        if (!MemAWrite (context, address, Rt, addr_byte_size))
10339            return false;
10340
10341        // MemA[address+4,4] = R[t2];
10342        uint32_t Rt2 = ReadCoreReg (t2, &success);
10343        if (!success)
10344            return false;
10345
10346        data_reg.num = dwarf_r0 + t2;
10347
10348        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10349
10350        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10351            return false;
10352
10353        // if wback then R[n] = offset_addr;
10354        if (wback)
10355        {
10356            context.type = eContextAdjustBaseRegister;
10357            context.SetAddress (offset_addr);
10358
10359            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10360                return false;
10361
10362        }
10363    }
10364    return true;
10365}
10366
10367// A8.6.319 VLDM
10368// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10369// an ARM core register.
10370bool
10371EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10372{
10373#if 0
10374    if ConditionPassed() then
10375        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10376        address = if add then R[n] else R[n]-imm32;
10377        if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10378        for r = 0 to regs-1
10379            if single_regs then
10380                S[d+r] = MemA[address,4]; address = address+4;
10381            else
10382                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10383                // Combine the word-aligned words in the correct order for current endianness.
10384                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10385#endif
10386
10387    bool success = false;
10388
10389    if (ConditionPassed(opcode))
10390    {
10391        bool single_regs;
10392        bool add;
10393        bool wback;
10394        uint32_t d;
10395        uint32_t n;
10396        uint32_t imm32;
10397        uint32_t regs;
10398
10399        switch (encoding)
10400        {
10401            case eEncodingT1:
10402            case eEncodingA1:
10403                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10404                // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10405                // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10406                // if P == U && W == ‘1’ then UNDEFINED;
10407                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10408                    return false;
10409
10410                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10411                // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10412                single_regs = false;
10413                add = BitIsSet (opcode, 23);
10414                wback = BitIsSet (opcode, 21);
10415
10416                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10417                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10418                n = Bits32 (opcode, 19, 16);
10419                imm32 = Bits32 (opcode, 7, 0) << 2;
10420
10421                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FLDMX”.
10422                regs = Bits32 (opcode, 7, 0) / 2;
10423
10424                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10425                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10426                    return false;
10427
10428                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10429                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10430                    return false;
10431
10432                break;
10433
10434            case eEncodingT2:
10435            case eEncodingA2:
10436                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10437                // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10438                // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10439                // if P == U && W == ‘1’ then UNDEFINED;
10440                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10441                    return false;
10442
10443                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10444                // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10445                single_regs = true;
10446                add = BitIsSet (opcode, 23);
10447                wback = BitIsSet (opcode, 21);
10448                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10449                n = Bits32 (opcode, 19, 16);
10450
10451                // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10452                imm32 = Bits32 (opcode, 7, 0) << 2;
10453                regs = Bits32 (opcode, 7, 0);
10454
10455                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10456                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10457                    return false;
10458
10459                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10460                if ((regs == 0) || ((d + regs) > 32))
10461                    return false;
10462                break;
10463
10464            default:
10465                return false;
10466        }
10467
10468        Register base_reg;
10469        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10470
10471        uint32_t Rn = ReadCoreReg (n, &success);
10472        if (!success)
10473            return false;
10474
10475        // address = if add then R[n] else R[n]-imm32;
10476        addr_t address;
10477        if (add)
10478            address = Rn;
10479        else
10480            address = Rn - imm32;
10481
10482        // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10483        EmulateInstruction::Context context;
10484
10485        if (wback)
10486        {
10487            uint32_t value;
10488            if (add)
10489                value = Rn + imm32;
10490            else
10491                value = Rn - imm32;
10492
10493            context.type = eContextAdjustBaseRegister;
10494            context.SetImmediateSigned (value - Rn);
10495            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10496                return false;
10497
10498        }
10499
10500        const uint32_t addr_byte_size = GetAddressByteSize();
10501        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10502
10503        context.type = eContextRegisterLoad;
10504
10505        // for r = 0 to regs-1
10506        for (uint32_t r = 0; r < regs; ++r)
10507        {
10508            if (single_regs)
10509            {
10510                // S[d+r] = MemA[address,4]; address = address+4;
10511                context.SetRegisterPlusOffset (base_reg, address - Rn);
10512
10513                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10514                if (!success)
10515                    return false;
10516
10517                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10518                    return false;
10519
10520                address = address + 4;
10521            }
10522            else
10523            {
10524                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10525                context.SetRegisterPlusOffset (base_reg, address - Rn);
10526                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10527                if (!success)
10528                    return false;
10529
10530                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10531                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10532                if (!success)
10533                    return false;
10534
10535                address = address + 8;
10536                // // Combine the word-aligned words in the correct order for current endianness.
10537                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10538                uint64_t data;
10539                if (m_byte_order == eByteOrderBig)
10540                {
10541                    data = word1;
10542                    data = (data << 32) | word2;
10543                }
10544                else
10545                {
10546                    data = word2;
10547                    data = (data << 32) | word1;
10548                }
10549
10550                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10551                    return false;
10552            }
10553        }
10554    }
10555    return true;
10556}
10557
10558// A8.6.399 VSTM
10559// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10560// ARM core register.
10561bool
10562EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10563{
10564#if 0
10565    if ConditionPassed() then
10566        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10567        address = if add then R[n] else R[n]-imm32;
10568        if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10569        for r = 0 to regs-1
10570            if single_regs then
10571                MemA[address,4] = S[d+r]; address = address+4;
10572            else
10573                // Store as two word-aligned words in the correct order for current endianness.
10574                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10575                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10576                address = address+8;
10577#endif
10578
10579    bool success = false;
10580
10581    if (ConditionPassed (opcode))
10582    {
10583        bool single_regs;
10584        bool add;
10585        bool wback;
10586        uint32_t d;
10587        uint32_t n;
10588        uint32_t imm32;
10589        uint32_t regs;
10590
10591        switch (encoding)
10592        {
10593            case eEncodingT1:
10594            case eEncodingA1:
10595                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10596                // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10597                // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10598                // if P == U && W == ‘1’ then UNDEFINED;
10599                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10600                    return false;
10601
10602                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10603                // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10604                single_regs = false;
10605                add = BitIsSet (opcode, 23);
10606                wback = BitIsSet (opcode, 21);
10607
10608                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10609                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10610                n = Bits32 (opcode, 19, 16);
10611                imm32 = Bits32 (opcode, 7, 0) << 2;
10612
10613                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FSTMX”.
10614                regs = Bits32 (opcode, 7, 0) / 2;
10615
10616                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10617                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10618                    return false;
10619
10620                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10621                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10622                    return false;
10623
10624                break;
10625
10626            case eEncodingT2:
10627            case eEncodingA2:
10628                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10629                // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10630                // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10631                // if P == U && W == ‘1’ then UNDEFINED;
10632                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10633                    return false;
10634
10635                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10636                // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10637                single_regs = true;
10638                add = BitIsSet (opcode, 23);
10639                wback = BitIsSet (opcode, 21);
10640                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10641                n = Bits32 (opcode, 19, 16);
10642
10643                // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10644                imm32 = Bits32 (opcode, 7, 0) << 2;
10645                regs = Bits32 (opcode, 7, 0);
10646
10647                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10648                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10649                    return false;
10650
10651                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10652                if ((regs == 0) || ((d + regs) > 32))
10653                    return false;
10654
10655                break;
10656
10657            default:
10658                return false;
10659        }
10660
10661        Register base_reg;
10662        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10663
10664        uint32_t Rn = ReadCoreReg (n, &success);
10665        if (!success)
10666            return false;
10667
10668        // address = if add then R[n] else R[n]-imm32;
10669        addr_t address;
10670        if (add)
10671            address = Rn;
10672        else
10673            address = Rn - imm32;
10674
10675        EmulateInstruction::Context context;
10676        // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10677        if (wback)
10678        {
10679            uint32_t value;
10680            if (add)
10681                value = Rn + imm32;
10682            else
10683                value = Rn - imm32;
10684
10685            context.type = eContextAdjustBaseRegister;
10686            context.SetRegisterPlusOffset (base_reg, value - Rn);
10687
10688            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10689                return false;
10690        }
10691
10692        const uint32_t addr_byte_size = GetAddressByteSize();
10693        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10694
10695        context.type = eContextRegisterStore;
10696        // for r = 0 to regs-1
10697        for (int r = 0; r < regs; ++r)
10698        {
10699            Register data_reg;
10700            data_reg.SetRegister (eRegisterKindDWARF, 0);
10701            if (single_regs)
10702            {
10703                // MemA[address,4] = S[d+r]; address = address+4;
10704                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10705                if (!success)
10706                    return false;
10707
10708                data_reg.num = start_reg + d + r;
10709                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10710                if (!MemAWrite (context, address, data, addr_byte_size))
10711                    return false;
10712
10713                address = address + 4;
10714            }
10715            else
10716            {
10717                // // Store as two word-aligned words in the correct order for current endianness.
10718                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10719                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10720                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10721                if (!success)
10722                    return false;
10723
10724                data_reg.num = start_reg + d + r;
10725
10726                if (m_byte_order == eByteOrderBig)
10727                {
10728                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10729                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10730                        return false;
10731
10732                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10733                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10734                        return false;
10735                }
10736                else
10737                {
10738                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10739                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10740                        return false;
10741
10742                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10743                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10744                        return false;
10745                }
10746                // address = address+8;
10747                address = address + 8;
10748            }
10749        }
10750    }
10751    return true;
10752}
10753
10754// A8.6.320
10755// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10756// an optional offset.
10757bool
10758EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10759{
10760#if 0
10761    if ConditionPassed() then
10762        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10763        base = if n == 15 then Align(PC,4) else R[n];
10764        address = if add then (base + imm32) else (base - imm32);
10765        if single_reg then
10766            S[d] = MemA[address,4];
10767        else
10768            word1 = MemA[address,4]; word2 = MemA[address+4,4];
10769            // Combine the word-aligned words in the correct order for current endianness.
10770            D[d] = if BigEndian() then word1:word2 else word2:word1;
10771#endif
10772
10773    bool success = false;
10774
10775    if (ConditionPassed (opcode))
10776    {
10777        bool single_reg;
10778        bool add;
10779        uint32_t imm32;
10780        uint32_t d;
10781        uint32_t n;
10782
10783        switch (encoding)
10784        {
10785            case eEncodingT1:
10786            case eEncodingA1:
10787                // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10788                single_reg = false;
10789                add = BitIsSet (opcode, 23);
10790                imm32 = Bits32 (opcode, 7, 0) << 2;
10791
10792                // d = UInt(D:Vd); n = UInt(Rn);
10793                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10794                n = Bits32 (opcode, 19, 16);
10795
10796                break;
10797
10798            case eEncodingT2:
10799            case eEncodingA2:
10800                // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10801                single_reg = true;
10802                add = BitIsSet (opcode, 23);
10803                imm32 = Bits32 (opcode, 7, 0) << 2;
10804
10805                // d = UInt(Vd:D); n = UInt(Rn);
10806                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10807                n = Bits32 (opcode, 19, 16);
10808
10809                break;
10810
10811            default:
10812                return false;
10813        }
10814        Register base_reg;
10815        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10816
10817        uint32_t Rn = ReadCoreReg (n, &success);
10818        if (!success)
10819            return false;
10820
10821        // base = if n == 15 then Align(PC,4) else R[n];
10822        uint32_t base;
10823        if (n == 15)
10824            base = AlignPC (Rn);
10825        else
10826            base = Rn;
10827
10828        // address = if add then (base + imm32) else (base - imm32);
10829        addr_t address;
10830        if (add)
10831            address = base + imm32;
10832        else
10833            address = base - imm32;
10834
10835        const uint32_t addr_byte_size = GetAddressByteSize();
10836        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
10837
10838        EmulateInstruction::Context context;
10839        context.type = eContextRegisterLoad;
10840        context.SetRegisterPlusOffset (base_reg, address - base);
10841
10842        if (single_reg)
10843        {
10844            // S[d] = MemA[address,4];
10845            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10846            if (!success)
10847                return false;
10848
10849            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
10850                return false;
10851        }
10852        else
10853        {
10854            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
10855            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10856            if (!success)
10857                return false;
10858
10859            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
10860            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10861            if (!success)
10862                return false;
10863            // // Combine the word-aligned words in the correct order for current endianness.
10864            // D[d] = if BigEndian() then word1:word2 else word2:word1;
10865            uint64_t data64;
10866            if (m_byte_order == eByteOrderBig)
10867            {
10868                data64 = word1;
10869                data64 = (data64 << 32) | word2;
10870            }
10871            else
10872            {
10873                data64 = word2;
10874                data64 = (data64 << 32) | word1;
10875            }
10876
10877            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
10878                return false;
10879        }
10880    }
10881    return true;
10882}
10883
10884// A8.6.400 VSTR
10885// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
10886// optional offset.
10887bool
10888EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
10889{
10890#if 0
10891    if ConditionPassed() then
10892        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10893        address = if add then (R[n] + imm32) else (R[n] - imm32);
10894        if single_reg then
10895            MemA[address,4] = S[d];
10896        else
10897            // Store as two word-aligned words in the correct order for current endianness.
10898            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
10899            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
10900#endif
10901
10902    bool success = false;
10903
10904    if (ConditionPassed (opcode))
10905    {
10906        bool single_reg;
10907        bool add;
10908        uint32_t imm32;
10909        uint32_t d;
10910        uint32_t n;
10911
10912        switch (encoding)
10913        {
10914            case eEncodingT1:
10915            case eEncodingA1:
10916                // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10917                single_reg = false;
10918                add = BitIsSet (opcode, 23);
10919                imm32 = Bits32 (opcode, 7, 0) << 2;
10920
10921                // d = UInt(D:Vd); n = UInt(Rn);
10922                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10923                n = Bits32 (opcode, 19, 16);
10924
10925                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
10926                if ((n == 15) && (CurrentInstrSet() != eModeARM))
10927                    return false;
10928
10929                break;
10930
10931            case eEncodingT2:
10932            case eEncodingA2:
10933                // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10934                single_reg = true;
10935                add = BitIsSet (opcode, 23);
10936                imm32 = Bits32 (opcode, 7, 0) << 2;
10937
10938                // d = UInt(Vd:D); n = UInt(Rn);
10939                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10940                n = Bits32 (opcode, 19, 16);
10941
10942                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
10943                if ((n == 15) && (CurrentInstrSet() != eModeARM))
10944                    return false;
10945
10946                break;
10947
10948            default:
10949                return false;
10950        }
10951
10952        Register base_reg;
10953        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10954
10955        uint32_t Rn = ReadCoreReg (n, &success);
10956        if (!success)
10957            return false;
10958
10959        // address = if add then (R[n] + imm32) else (R[n] - imm32);
10960        addr_t address;
10961        if (add)
10962            address = Rn + imm32;
10963        else
10964            address = Rn - imm32;
10965
10966        const uint32_t addr_byte_size = GetAddressByteSize();
10967        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
10968
10969        Register data_reg;
10970        data_reg.SetRegister (eRegisterKindDWARF, start_reg + d);
10971        EmulateInstruction::Context context;
10972        context.type = eContextRegisterStore;
10973        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10974
10975        if (single_reg)
10976        {
10977            // MemA[address,4] = S[d];
10978            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
10979            if (!success)
10980                return false;
10981
10982            if (!MemAWrite (context, address, data, addr_byte_size))
10983                return false;
10984        }
10985        else
10986        {
10987            // // Store as two word-aligned words in the correct order for current endianness.
10988            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
10989            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
10990            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
10991            if (!success)
10992                return false;
10993
10994            if (m_byte_order == eByteOrderBig)
10995            {
10996                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10997                    return false;
10998
10999                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11000                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11001                    return false;
11002            }
11003            else
11004            {
11005                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11006                    return false;
11007
11008                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11009                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11010                    return false;
11011            }
11012        }
11013    }
11014    return true;
11015}
11016
11017// A8.6.307 VLDI1 (multiple single elements)
11018// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11019// element of each register is loaded.
11020bool
11021EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11022{
11023#if 0
11024    if ConditionPassed() then
11025        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11026        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11027        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11028        for r = 0 to regs-1
11029            for e = 0 to elements-1
11030                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11031                address = address + ebytes;
11032#endif
11033
11034    bool success = false;
11035
11036    if (ConditionPassed (opcode))
11037    {
11038        uint32_t regs;
11039        uint32_t alignment;
11040        uint32_t ebytes;
11041        uint32_t esize;
11042        uint32_t elements;
11043        uint32_t d;
11044        uint32_t n;
11045        uint32_t m;
11046        bool wback;
11047        bool register_index;
11048
11049        switch (encoding)
11050        {
11051            case eEncodingT1:
11052            case eEncodingA1:
11053            {
11054                // case type of
11055                    // when ‘0111’
11056                        // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11057                    // when ‘1010’
11058                        // regs = 2; if align == ‘11’ then UNDEFINED;
11059                    // when ‘0110’
11060                        // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11061                    // when ‘0010’
11062                        // regs = 4;
11063                    // otherwise
11064                        // SEE “Related encodings”;
11065                uint32_t type = Bits32 (opcode, 11, 8);
11066                uint32_t align = Bits32 (opcode, 5, 4);
11067                if (type == 7) // '0111'
11068                {
11069                    regs = 1;
11070                    if (BitIsSet (align, 1))
11071                        return false;
11072                }
11073                else if (type == 10) // '1010'
11074                {
11075                    regs = 2;
11076                    if (align == 3)
11077                        return false;
11078
11079                }
11080                else if (type == 6) // '0110'
11081                {
11082                    regs = 3;
11083                    if (BitIsSet (align, 1))
11084                        return false;
11085                }
11086                else if (type == 2) // '0010'
11087                {
11088                    regs = 4;
11089                }
11090                else
11091                    return false;
11092
11093                // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11094                if (align == 0)
11095                    alignment = 1;
11096                else
11097                    alignment = 4 << align;
11098
11099                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11100                ebytes = 1 << Bits32 (opcode, 7, 6);
11101                esize = 8 * ebytes;
11102                elements = 8 / ebytes;
11103
11104                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11105                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11106                n = Bits32 (opcode, 19, 15);
11107                m = Bits32 (opcode, 3, 0);
11108
11109                // wback = (m != 15); register_index = (m != 15 && m != 13);
11110                wback = (m != 15);
11111                register_index = ((m != 15) && (m != 13));
11112
11113                // if d+regs > 32 then UNPREDICTABLE;
11114                if ((d + regs) > 32)
11115                    return false;
11116            }
11117                break;
11118
11119            default:
11120                return false;
11121        }
11122
11123        Register base_reg;
11124        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11125
11126        uint32_t Rn = ReadCoreReg (n, &success);
11127        if (!success)
11128            return false;
11129
11130        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11131        addr_t address = Rn;
11132        if ((address % alignment) != 0)
11133            return false;
11134
11135        EmulateInstruction::Context context;
11136        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11137        if (wback)
11138        {
11139            uint32_t Rm = ReadCoreReg (m, &success);
11140            if (!success)
11141                return false;
11142
11143            uint32_t offset;
11144            if (register_index)
11145                offset = Rm;
11146            else
11147                offset = 8 * regs;
11148
11149            uint32_t value = Rn + offset;
11150            context.type = eContextAdjustBaseRegister;
11151            context.SetRegisterPlusOffset (base_reg, offset);
11152
11153            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11154                return false;
11155
11156        }
11157
11158        // for r = 0 to regs-1
11159        for (int r = 0; r < regs; ++r)
11160        {
11161            // for e = 0 to elements-1
11162            uint64_t assembled_data = 0;
11163            for (int e = 0; e < elements; ++e)
11164            {
11165                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11166                context.type = eContextRegisterLoad;
11167                context.SetRegisterPlusOffset (base_reg, address - Rn);
11168                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11169                if (!success)
11170                    return false;
11171
11172                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11173
11174                // address = address + ebytes;
11175                address = address + ebytes;
11176            }
11177            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11178                return false;
11179        }
11180    }
11181    return true;
11182}
11183
11184// A8.6.308 VLD1 (single element to one lane)
11185//
11186bool
11187EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11188{
11189#if 0
11190    if ConditionPassed() then
11191        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11192        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11193        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11194        Elem[D[d],index,esize] = MemU[address,ebytes];
11195#endif
11196
11197    bool success = false;
11198
11199    if (ConditionPassed (opcode))
11200    {
11201        uint32_t ebytes;
11202        uint32_t esize;
11203        uint32_t index;
11204        uint32_t alignment;
11205        uint32_t d;
11206        uint32_t n;
11207        uint32_t m;
11208        bool wback;
11209        bool register_index;
11210
11211        switch (encoding)
11212        {
11213            case eEncodingT1:
11214            case eEncodingA1:
11215            {
11216                uint32_t size = Bits32 (opcode, 11, 10);
11217                uint32_t index_align = Bits32 (opcode, 7, 4);
11218                // if size == ‘11’ then SEE VLD1 (single element to all lanes);
11219                // if (size == 3)
11220                //    return EmulateVLD1SingleAll (opcode, encoding);
11221                // case size of
11222                if (size == 0) // when '00'
11223                {
11224                    // if index_align<0> != ‘0’ then UNDEFINED;
11225                    if (BitIsClear (index_align, 0))
11226                        return false;
11227
11228                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11229                    ebytes = 1;
11230                    esize = 8;
11231                    index = Bits32 (index_align, 3, 1);
11232                    alignment = 1;
11233                }
11234                else if (size == 1) // when ‘01’
11235                {
11236                    // if index_align<1> != ‘0’ then UNDEFINED;
11237                    if (BitIsClear (index_align, 1))
11238                        return false;
11239
11240                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11241                    ebytes = 2;
11242                    esize = 16;
11243                    index = Bits32 (index_align, 3, 2);
11244
11245                    // alignment = if index_align<0> == ‘0’ then 1 else 2;
11246                    if (BitIsClear (index_align, 0))
11247                        alignment = 1;
11248                    else
11249                        alignment = 2;
11250                }
11251                else if (size == 2) // when ‘10’
11252                {
11253                    // if index_align<2> != ‘0’ then UNDEFINED;
11254                    if (BitIsClear (index_align, 2))
11255                        return false;
11256
11257                    // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11258                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11259                        return false;
11260
11261                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11262                    ebytes = 4;
11263                    esize = 32;
11264                    index = Bit32 (index_align, 3);
11265
11266                    // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11267                    if (Bits32 (index_align, 1, 0) == 0)
11268                        alignment = 1;
11269                    else
11270                        alignment = 4;
11271                }
11272                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11273                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11274                n = Bits32 (opcode, 19, 16);
11275                m = Bits32 (opcode, 3, 0);
11276
11277                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11278                wback = (m != 15);
11279                register_index = ((m != 15) && (m != 13));
11280
11281                if (n == 15)
11282                    return false;
11283
11284            }
11285                break;
11286
11287            default:
11288                return false;
11289        }
11290
11291        Register base_reg;
11292        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11293
11294        uint32_t Rn = ReadCoreReg (n, &success);
11295        if (!success)
11296            return false;
11297
11298        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11299        addr_t address = Rn;
11300        if ((address % alignment) != 0)
11301            return false;
11302
11303        EmulateInstruction::Context context;
11304        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11305        if (wback)
11306        {
11307            uint32_t Rm = ReadCoreReg (m, &success);
11308            if (!success)
11309                return false;
11310
11311            uint32_t offset;
11312            if (register_index)
11313                offset = Rm;
11314            else
11315                offset = ebytes;
11316
11317            uint32_t value = Rn + offset;
11318
11319            context.type = eContextAdjustBaseRegister;
11320            context.SetRegisterPlusOffset (base_reg, offset);
11321
11322            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11323                return false;
11324        }
11325
11326        // Elem[D[d],index,esize] = MemU[address,ebytes];
11327        uint32_t element = MemURead (context, address, esize, 0, &success);
11328        if (!success)
11329            return false;
11330
11331        element = element << (index * esize);
11332
11333        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11334        if (!success)
11335            return false;
11336
11337        uint64_t all_ones = -1;
11338        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11339                                                          // at element & to the right of element.
11340        if (index > 0)
11341            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11342                                                                     // now mask should be 0's where element goes & 1's
11343                                                                     // everywhere else.
11344
11345        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11346        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11347
11348        context.type = eContextRegisterLoad;
11349        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11350            return false;
11351    }
11352    return true;
11353}
11354
11355// A8.6.391 VST1 (multiple single elements)
11356// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11357// interleaving.  Every element of each register is stored.
11358bool
11359EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11360{
11361#if 0
11362    if ConditionPassed() then
11363        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11364        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11365        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11366        for r = 0 to regs-1
11367            for e = 0 to elements-1
11368                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11369                address = address + ebytes;
11370#endif
11371
11372    bool success = false;
11373
11374    if (ConditionPassed (opcode))
11375    {
11376        uint32_t regs;
11377        uint32_t alignment;
11378        uint32_t ebytes;
11379        uint32_t esize;
11380        uint32_t elements;
11381        uint32_t d;
11382        uint32_t n;
11383        uint32_t m;
11384        bool wback;
11385        bool register_index;
11386
11387        switch (encoding)
11388        {
11389            case eEncodingT1:
11390            case eEncodingA1:
11391            {
11392                uint32_t type = Bits32 (opcode, 11, 8);
11393                uint32_t align = Bits32 (opcode, 5, 4);
11394
11395                // case type of
11396                if (type == 7)    // when ‘0111’
11397                {
11398                    // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11399                    regs = 1;
11400                    if (BitIsSet (align, 1))
11401                        return false;
11402                }
11403                else if (type == 10) // when ‘1010’
11404                {
11405                    // regs = 2; if align == ‘11’ then UNDEFINED;
11406                    regs = 2;
11407                    if (align == 3)
11408                        return false;
11409                }
11410                else if (type == 6) // when ‘0110’
11411                {
11412                    // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11413                    regs = 3;
11414                    if (BitIsSet (align, 1))
11415                        return false;
11416                }
11417                else if (type == 2) // when ‘0010’
11418                    // regs = 4;
11419                    regs = 4;
11420                else // otherwise
11421                    // SEE “Related encodings”;
11422                    return false;
11423
11424                // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11425                if (align == 0)
11426                    alignment = 0;
11427                else
11428                    alignment = 4 << align;
11429
11430                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11431                ebytes = 1 << Bits32 (opcode,7, 6);
11432                esize = 8 * ebytes;
11433                elements = 8 / ebytes;
11434
11435                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11436                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11437                n = Bits32 (opcode, 19, 16);
11438                m = Bits32 (opcode, 3, 0);
11439
11440                // wback = (m != 15); register_index = (m != 15 && m != 13);
11441                wback = (m != 15);
11442                register_index = ((m != 15) && (m != 13));
11443
11444                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11445                if ((d + regs) > 32)
11446                    return false;
11447
11448                if (n == 15)
11449                    return false;
11450
11451            }
11452                break;
11453
11454            default:
11455                return false;
11456        }
11457
11458        Register base_reg;
11459        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11460
11461        uint32_t Rn = ReadCoreReg (n, &success);
11462        if (!success)
11463            return false;
11464
11465        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11466        addr_t address = Rn;
11467        if ((address % alignment) != 0)
11468            return false;
11469
11470        EmulateInstruction::Context context;
11471        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11472        if (wback)
11473        {
11474            uint32_t Rm = ReadCoreReg (m, &success);
11475            if (!success)
11476                return false;
11477
11478            uint32_t offset;
11479            if (register_index)
11480                offset = Rm;
11481            else
11482                offset = 8 * regs;
11483
11484            context.type = eContextAdjustBaseRegister;
11485            context.SetRegisterPlusOffset (base_reg, offset);
11486
11487            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11488                return false;
11489        }
11490
11491        context.type = eContextRegisterStore;
11492        Register data_reg;
11493        data_reg.SetRegister (eRegisterKindDWARF, 0);
11494        // for r = 0 to regs-1
11495        for (int r = 0; r < regs; ++r)
11496        {
11497            data_reg.num = dwarf_d0 + d + r;
11498            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11499            if (!success)
11500                return false;
11501
11502             // for e = 0 to elements-1
11503            for (int e = 0; e < elements; ++e)
11504            {
11505                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11506                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11507
11508                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11509                if (!MemUWrite (context, address, word, ebytes))
11510                    return false;
11511
11512                // address = address + ebytes;
11513                address = address + ebytes;
11514            }
11515        }
11516    }
11517    return true;
11518}
11519
11520// A8.6.392 VST1 (single element from one lane)
11521// This instruction stores one element to memory from one element of a register.
11522bool
11523EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11524{
11525#if 0
11526    if ConditionPassed() then
11527        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11528        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11529        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11530        MemU[address,ebytes] = Elem[D[d],index,esize];
11531#endif
11532
11533    bool success = false;
11534
11535    if (ConditionPassed (opcode))
11536    {
11537        uint32_t ebytes;
11538        uint32_t esize;
11539        uint32_t index;
11540        uint32_t alignment;
11541        uint32_t d;
11542        uint32_t n;
11543        uint32_t m;
11544        bool wback;
11545        bool register_index;
11546
11547        switch (encoding)
11548        {
11549            case eEncodingT1:
11550            case eEncodingA1:
11551            {
11552                uint32_t size = Bits32 (opcode, 11, 10);
11553                uint32_t index_align = Bits32 (opcode, 7, 4);
11554
11555                // if size == ‘11’ then UNDEFINED;
11556                if (size == 3)
11557                    return false;
11558
11559                // case size of
11560                if (size == 0) // when ‘00’
11561                {
11562                    // if index_align<0> != ‘0’ then UNDEFINED;
11563                    if (BitIsClear (index_align, 0))
11564                        return false;
11565                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11566                    ebytes = 1;
11567                    esize = 8;
11568                    index = Bits32 (index_align, 3, 1);
11569                    alignment = 1;
11570                }
11571                else if (size == 1) // when ‘01’
11572                {
11573                    // if index_align<1> != ‘0’ then UNDEFINED;
11574                    if (BitIsClear (index_align, 1))
11575                        return false;
11576
11577                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11578                    ebytes = 2;
11579                    esize = 16;
11580                    index = Bits32 (index_align, 3, 2);
11581
11582                    // alignment = if index_align<0> == ‘0’ then 1 else 2;
11583                    if (BitIsClear (index_align, 0))
11584                        alignment = 1;
11585                    else
11586                        alignment = 2;
11587                }
11588                else if (size == 2) // when ‘10’
11589                {
11590                    // if index_align<2> != ‘0’ then UNDEFINED;
11591                    if (BitIsClear (index_align, 2))
11592                        return false;
11593
11594                    // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11595                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11596                        return false;
11597
11598                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11599                    ebytes = 4;
11600                    esize = 32;
11601                    index = Bit32 (index_align, 3);
11602
11603                    // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11604                    if (Bits32 (index_align, 1, 0) == 0)
11605                        alignment = 1;
11606                    else
11607                        alignment = 4;
11608                }
11609                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11610                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11611                n = Bits32 (opcode, 19, 16);
11612                m = Bits32 (opcode, 3, 0);
11613
11614                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11615                wback = (m != 15);
11616                register_index = ((m != 15) && (m != 13));
11617
11618                if (n == 15)
11619                    return false;
11620            }
11621                break;
11622
11623            default:
11624                return false;
11625        }
11626
11627        Register base_reg;
11628        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11629
11630        uint32_t Rn = ReadCoreReg (n, &success);
11631        if (!success)
11632            return false;
11633
11634        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11635        addr_t address = Rn;
11636        if ((address % alignment) != 0)
11637            return false;
11638
11639        EmulateInstruction::Context context;
11640        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11641        if (wback)
11642        {
11643            uint32_t Rm = ReadCoreReg (m, &success);
11644            if (!success)
11645                return false;
11646
11647            uint32_t offset;
11648            if (register_index)
11649                offset = Rm;
11650            else
11651                offset = ebytes;
11652
11653            context.type = eContextAdjustBaseRegister;
11654            context.SetRegisterPlusOffset (base_reg, offset);
11655
11656            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11657                return false;
11658        }
11659
11660        // MemU[address,ebytes] = Elem[D[d],index,esize];
11661        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11662        if (!success)
11663            return false;
11664
11665        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11666
11667        Register data_reg;
11668        data_reg.SetRegister (eRegisterKindDWARF, dwarf_d0 + d);
11669        context.type = eContextRegisterStore;
11670        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11671
11672        if (!MemUWrite (context, address, word, ebytes))
11673            return false;
11674    }
11675    return true;
11676}
11677
11678// A8.6.309 VST1 (single element to all lanes)
11679//
11680bool
11681EmulateInstructionARM::EmulateVST1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11682{
11683#if 0
11684    if ConditionPassed() then
11685        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11686        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11687        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11688        replicated_element = Replicate(MemU[address,ebytes], elements);
11689        for r = 0 to regs-1
11690            D[d+r] = replicated_element;
11691#endif
11692
11693    bool success = false;
11694
11695    if (ConditionPassed (opcode))
11696    {
11697        uint32_t ebytes;
11698        uint32_t elements;
11699        uint32_t regs;
11700        uint32_t alignment;
11701        uint32_t d;
11702        uint32_t n;
11703        uint32_t m;
11704        bool wback;
11705        bool register_index;
11706
11707        switch (encoding)
11708        {
11709            case eEncodingT1:
11710            case eEncodingA1:
11711            {
11712                //if size == ‘11’ || (size == ‘00’ && a == ‘1’) then UNDEFINED;
11713                uint32_t size = Bits32 (opcode, 7, 6);
11714                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11715                    return false;
11716
11717                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == ‘0’ then 1 else 2;
11718                ebytes = 1 << size;
11719                elements = 8 / ebytes;
11720                if (BitIsClear (opcode, 5))
11721                    regs = 1;
11722                else
11723                    regs = 2;
11724
11725                //alignment = if a == ‘0’ then 1 else ebytes;
11726                if (BitIsClear (opcode, 4))
11727                    alignment = 1;
11728                else
11729                    alignment = ebytes;
11730
11731                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11732                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11733                n = Bits32 (opcode, 19, 16);
11734                m = Bits32 (opcode, 3, 0);
11735
11736                //wback = (m != 15); register_index = (m != 15 && m != 13);
11737                wback = (m != 15);
11738                register_index = ((m != 15) && (m != 13));
11739
11740                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11741                if ((d + regs) > 32)
11742                    return false;
11743
11744                if (n == 15)
11745                    return false;
11746            }
11747                break;
11748
11749            default:
11750                break;
11751        }
11752
11753        Register base_reg;
11754        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
11755
11756        uint32_t Rn = ReadCoreReg (n, &success);
11757        if (!success)
11758            return false;
11759
11760        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11761        addr_t address = Rn;
11762        if ((address % alignment) != 0)
11763            return false;
11764
11765        EmulateInstruction::Context context;
11766        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11767        if (wback)
11768        {
11769            uint32_t Rm = ReadCoreReg (m, &success);
11770            if (!success)
11771                return false;
11772
11773            uint32_t offset;
11774            if (register_index)
11775                offset = Rm;
11776            else
11777                offset = ebytes;
11778
11779            context.type = eContextAdjustBaseRegister;
11780            context.SetRegisterPlusOffset (base_reg, offset);
11781
11782            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11783                return false;
11784        }
11785
11786        // replicated_element = Replicate(MemU[address,ebytes], elements);
11787
11788        context.type = eContextRegisterLoad;
11789        uint64_t word = MemURead (context, address, ebytes, 0, &success);
11790        if (!success)
11791            return false;
11792
11793        uint64_t replicated_element;
11794        uint32_t esize = ebytes * 8;
11795        for (int e = 0; e < elements; ++e)
11796            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
11797
11798        // for r = 0 to regs-1
11799        for (int r = 0; r < regs; ++r)
11800        {
11801            // D[d+r] = replicated_element;
11802            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
11803                return false;
11804        }
11805    }
11806    return true;
11807}
11808
11809EmulateInstructionARM::ARMOpcode*
11810EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
11811{
11812    static ARMOpcode
11813    g_arm_opcodes[] =
11814    {
11815        //----------------------------------------------------------------------
11816        // Prologue instructions
11817        //----------------------------------------------------------------------
11818
11819        // push register(s)
11820        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
11821        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
11822
11823        // set r7 to point to a stack offset
11824        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
11825        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
11826        // copy the stack pointer to ip
11827        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
11828        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
11829        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
11830
11831        // adjust the stack pointer
11832        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
11833        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
11834
11835        // push one register
11836        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
11837        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
11838
11839        // vector push consecutive extension register(s)
11840        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
11841        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
11842
11843        //----------------------------------------------------------------------
11844        // Epilogue instructions
11845        //----------------------------------------------------------------------
11846
11847        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
11848        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
11849        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
11850        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
11851
11852        //----------------------------------------------------------------------
11853        // Supervisor Call (previously Software Interrupt)
11854        //----------------------------------------------------------------------
11855        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
11856
11857        //----------------------------------------------------------------------
11858        // Branch instructions
11859        //----------------------------------------------------------------------
11860        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
11861        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
11862        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
11863        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
11864        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
11865        // for example, "bx lr"
11866        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
11867        // bxj
11868        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
11869
11870        //----------------------------------------------------------------------
11871        // Data-processing instructions
11872        //----------------------------------------------------------------------
11873        // adc (immediate)
11874        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
11875        // adc (register)
11876        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11877        // add (immediate)
11878        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
11879        // add (register)
11880        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11881        // add (register-shifted register)
11882        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>m, <Rm>, <type> <RS>"},
11883        // adr
11884        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
11885        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
11886        // and (immediate)
11887        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
11888        // and (register)
11889        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11890        // bic (immediate)
11891        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
11892        // bic (register)
11893        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11894        // eor (immediate)
11895        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
11896        // eor (register)
11897        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11898        // orr (immediate)
11899        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
11900        // orr (register)
11901        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11902        // rsb (immediate)
11903        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
11904        // rsb (register)
11905        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11906        // rsc (immediate)
11907        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
11908        // rsc (register)
11909        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11910        // sbc (immediate)
11911        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
11912        // sbc (register)
11913        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
11914        // sub (immediate, ARM)
11915        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
11916        // sub (sp minus immediate)
11917        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
11918        // sub (register)
11919        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
11920        // teq (immediate)
11921        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
11922        // teq (register)
11923        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
11924        // tst (immediate)
11925        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
11926        // tst (register)
11927        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
11928
11929        // mov (immediate)
11930        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
11931        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
11932        // mov (register)
11933        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
11934        // mvn (immediate)
11935        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
11936        // mvn (register)
11937        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
11938        // cmn (immediate)
11939        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
11940        // cmn (register)
11941        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
11942        // cmp (immediate)
11943        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
11944        // cmp (register)
11945        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
11946        // asr (immediate)
11947        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
11948        // asr (register)
11949        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
11950        // lsl (immediate)
11951        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
11952        // lsl (register)
11953        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
11954        // lsr (immediate)
11955        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
11956        // lsr (register)
11957        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
11958        // rrx is a special case encoding of ror (immediate)
11959        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
11960        // ror (immediate)
11961        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
11962        // ror (register)
11963        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
11964        // mul
11965        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
11966
11967        //----------------------------------------------------------------------
11968        // Load instructions
11969        //----------------------------------------------------------------------
11970        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
11971        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
11972        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
11973        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
11974        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
11975        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
11976        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
11977        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
11978        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
11979        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
11980        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
11981        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
11982        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
11983        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
11984        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
11985        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
11986        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
11987        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
11988        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
11989        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
11990        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
11991        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
11992        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
11993        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
11994        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
11995
11996        //----------------------------------------------------------------------
11997        // Store instructions
11998        //----------------------------------------------------------------------
11999        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12000        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12001        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12002        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12003        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12004        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12005        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12006        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12007        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12008        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strc<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12009        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12010        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12011        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12012        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12013        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12014        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12015        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12016
12017        //----------------------------------------------------------------------
12018        // Other instructions
12019        //----------------------------------------------------------------------
12020        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12021        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12022        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12023        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12024        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12025
12026    };
12027    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12028
12029    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12030    {
12031        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
12032            return &g_arm_opcodes[i];
12033    }
12034    return NULL;
12035}
12036
12037
12038EmulateInstructionARM::ARMOpcode*
12039EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
12040{
12041
12042    static ARMOpcode
12043    g_thumb_opcodes[] =
12044    {
12045        //----------------------------------------------------------------------
12046        // Prologue instructions
12047        //----------------------------------------------------------------------
12048
12049        // push register(s)
12050        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12051        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12052        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12053
12054        // set r7 to point to a stack offset
12055        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12056        // copy the stack pointer to r7
12057        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12058        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12059        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12060
12061        // PC-relative load into register (see also EmulateADDSPRm)
12062        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12063
12064        // adjust the stack pointer
12065        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12066        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12067        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12068        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12069        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12070
12071        // vector push consecutive extension register(s)
12072        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12073        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12074
12075        //----------------------------------------------------------------------
12076        // Epilogue instructions
12077        //----------------------------------------------------------------------
12078
12079        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12080        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12081        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12082        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12083        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12084        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12085        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12086
12087        //----------------------------------------------------------------------
12088        // Supervisor Call (previously Software Interrupt)
12089        //----------------------------------------------------------------------
12090        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12091
12092        //----------------------------------------------------------------------
12093        // If Then makes up to four following instructions conditional.
12094        //----------------------------------------------------------------------
12095        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12096
12097        //----------------------------------------------------------------------
12098        // Branch instructions
12099        //----------------------------------------------------------------------
12100        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12101        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12102        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12103        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12104        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12105        // J1 == J2 == 1
12106        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12107        // J1 == J2 == 1
12108        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12109        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12110        // for example, "bx lr"
12111        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12112        // bxj
12113        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12114        // compare and branch
12115        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12116        // table branch byte
12117        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12118        // table branch halfword
12119        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12120
12121        //----------------------------------------------------------------------
12122        // Data-processing instructions
12123        //----------------------------------------------------------------------
12124        // adc (immediate)
12125        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12126        // adc (register)
12127        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12128        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12129        // add (register)
12130        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12131        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12132        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12133        // adr
12134        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12135        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12136        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12137        // and (immediate)
12138        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12139        // and (register)
12140        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12141        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12142        // bic (immediate)
12143        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12144        // bic (register)
12145        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12146        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12147        // eor (immediate)
12148        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12149        // eor (register)
12150        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12151        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12152        // orr (immediate)
12153        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12154        // orr (register)
12155        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12156        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12157        // rsb (immediate)
12158        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12159        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12160        // rsb (register)
12161        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12162        // sbc (immediate)
12163        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12164        // sbc (register)
12165        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12166        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12167        // add (immediate, Thumb)
12168        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12169        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12170        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12171        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12172        // sub (immediate, Thumb)
12173        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12174        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12175        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12176        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12177        // sub (sp minus immediate)
12178        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12179        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12180        // sub (register)
12181        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12182        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12183        // teq (immediate)
12184        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12185        // teq (register)
12186        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12187        // tst (immediate)
12188        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12189        // tst (register)
12190        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12191        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12192
12193
12194        // move from high register to high register
12195        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12196        // move from low register to low register
12197        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12198        // mov{s}<c>.w <Rd>, <Rm>
12199        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12200        // move immediate
12201        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12202        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12203        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12204        // mvn (immediate)
12205        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12206        // mvn (register)
12207        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12208        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12209        // cmn (immediate)
12210        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12211        // cmn (register)
12212        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12213        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12214        // cmp (immediate)
12215        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12216        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12217        // cmp (register) (Rn and Rm both from r0-r7)
12218        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12219        // cmp (register) (Rn and Rm not both from r0-r7)
12220        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12221        // asr (immediate)
12222        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12223        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12224        // asr (register)
12225        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12226        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12227        // lsl (immediate)
12228        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12229        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12230        // lsl (register)
12231        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12232        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12233        // lsr (immediate)
12234        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12235        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12236        // lsr (register)
12237        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12238        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12239        // rrx is a special case encoding of ror (immediate)
12240        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12241        // ror (immediate)
12242        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12243        // ror (register)
12244        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12245        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12246        // mul
12247        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12248        // mul
12249        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12250
12251        //----------------------------------------------------------------------
12252        // Load instructions
12253        //----------------------------------------------------------------------
12254        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12255        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12256        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12257        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12258        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12259        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12260        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12261                  // Thumb2 PC-relative load into register
12262        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12263        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12264        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12265        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12266        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12267        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[>Rn>, #+/-<imm8>]{!}" },
12268        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12269        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12270        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12271        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12272        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12273        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12274        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12275        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12276        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12277        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12278        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12279        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12280        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12281        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12282        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12283        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12284        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12285        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12286        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12287        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt?, <Rt2>, [<Rn>,#+/-<imm>]!"},
12288        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12289        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12290        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12291        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12292        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12293        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12294        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12295
12296        //----------------------------------------------------------------------
12297        // Store instructions
12298        //----------------------------------------------------------------------
12299        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12300        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12301        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12302        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12303        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12304        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12305        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12306        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12307        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12308        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12309        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12310        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12311        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12312        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12313        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12314        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12315        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12316        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12317        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12318        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12319        { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12320        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12321
12322        //----------------------------------------------------------------------
12323        // Other instructions
12324        //----------------------------------------------------------------------
12325        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12326        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12327        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12328        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12329        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12330        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12331        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12332        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12333        { 0xffd00000, 0xe8100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12334        { 0xffd00000, 0xe9900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }
12335
12336    };
12337
12338    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12339    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12340    {
12341        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
12342            return &g_thumb_opcodes[i];
12343    }
12344    return NULL;
12345}
12346
12347bool
12348EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12349{
12350    m_arm_isa = 0;
12351    const char *arch_cstr = arch.GetArchitectureName ();
12352    if (arch_cstr)
12353    {
12354        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12355        else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
12356        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12357        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12358        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12359        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12360        else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
12361        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12362        else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
12363        else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
12364    }
12365    return m_arm_isa != 0;
12366}
12367
12368
12369bool
12370EmulateInstructionARM::ReadInstruction ()
12371{
12372    bool success = false;
12373    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12374    if (success)
12375    {
12376        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12377        if (success)
12378        {
12379            Context read_inst_context;
12380            read_inst_context.type = eContextReadOpcode;
12381            read_inst_context.SetNoArgs ();
12382
12383            if (m_opcode_cpsr & MASK_CPSR_T)
12384            {
12385                m_opcode_mode = eModeThumb;
12386                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12387
12388                if (success)
12389                {
12390                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12391                    {
12392                        m_opcode.SetOpcode16 (thumb_opcode);
12393                    }
12394                    else
12395                    {
12396                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12397                    }
12398                }
12399            }
12400            else
12401            {
12402                m_opcode_mode = eModeARM;
12403                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12404            }
12405        }
12406    }
12407    if (!success)
12408    {
12409        m_opcode_mode = eModeInvalid;
12410        m_opcode_pc = LLDB_INVALID_ADDRESS;
12411    }
12412    return success;
12413}
12414
12415uint32_t
12416EmulateInstructionARM::ArchVersion ()
12417{
12418    return m_arm_isa;
12419}
12420
12421bool
12422EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
12423{
12424    if (m_opcode_cpsr == 0)
12425        return false;
12426
12427    const uint32_t cond = CurrentCond (opcode);
12428
12429    if (cond == UINT32_MAX)
12430        return false;
12431
12432    bool result = false;
12433    switch (UnsignedBits(cond, 3, 1))
12434    {
12435    case 0: result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; break;
12436    case 1: result = (m_opcode_cpsr & MASK_CPSR_C) != 0; break;
12437    case 2: result = (m_opcode_cpsr & MASK_CPSR_N) != 0; break;
12438    case 3: result = (m_opcode_cpsr & MASK_CPSR_V) != 0; break;
12439    case 4: result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); break;
12440    case 5:
12441        {
12442            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12443            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12444            result = n == v;
12445        }
12446        break;
12447    case 6:
12448        {
12449            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12450            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12451            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12452        }
12453        break;
12454    case 7:
12455        result = true;
12456        break;
12457    }
12458
12459    if (cond & 1)
12460        result = !result;
12461    return result;
12462}
12463
12464uint32_t
12465EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12466{
12467    switch (m_opcode_mode)
12468    {
12469    default:
12470    case eModeInvalid:
12471        break;
12472
12473    case eModeARM:
12474        return UnsignedBits(opcode, 31, 28);
12475
12476    case eModeThumb:
12477        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12478        // 'cond' field of the encoding.
12479        {
12480            const uint32_t byte_size = m_opcode.GetByteSize();
12481            if (byte_size == 2)
12482            {
12483                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
12484                    return Bits32(opcode, 11, 7);
12485            }
12486            else
12487            {
12488                assert (byte_size == 4);
12489                if (Bits32(opcode, 31, 27) == 0x1e &&
12490                    Bits32(opcode, 15, 14) == 0x02 &&
12491                    Bits32(opcode, 12, 12) == 0x00 &&
12492                    Bits32(opcode, 25, 22) <= 0x0d)
12493                {
12494                    return Bits32(opcode, 25, 22);
12495                }
12496            }
12497
12498            return m_it_session.GetCond();
12499        }
12500    }
12501    return UINT32_MAX;  // Return invalid value
12502}
12503
12504bool
12505EmulateInstructionARM::InITBlock()
12506{
12507    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
12508}
12509
12510bool
12511EmulateInstructionARM::LastInITBlock()
12512{
12513    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
12514}
12515
12516bool
12517EmulateInstructionARM::BadMode (uint32_t mode)
12518{
12519
12520    switch (mode)
12521    {
12522        case 16: return false; // '10000'
12523        case 17: return false; // '10001'
12524        case 18: return false; // '10010'
12525        case 19: return false; // '10011'
12526        case 22: return false; // '10110'
12527        case 23: return false; // '10111'
12528        case 27: return false; // '11011'
12529        case 31: return false; // '11111'
12530        default: return true;
12531    }
12532    return true;
12533}
12534
12535bool
12536EmulateInstructionARM::CurrentModeIsPrivileged ()
12537{
12538    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
12539
12540    if (BadMode (mode))
12541        return false;
12542
12543    if (mode == 16)
12544                  return false;
12545
12546    return true;
12547}
12548
12549void
12550EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
12551{
12552    bool privileged = CurrentModeIsPrivileged();
12553
12554    uint32_t tmp_cpsr = 0;
12555
12556    tmp_cpsr = tmp_cpsr | (Bits32 (m_opcode_cpsr, 23, 20) << 20);
12557
12558    if (BitIsSet (bytemask, 3))
12559    {
12560        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
12561        if (affect_execstate)
12562            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
12563    }
12564
12565    if (BitIsSet (bytemask, 2))
12566    {
12567        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
12568    }
12569
12570    if (BitIsSet (bytemask, 1))
12571    {
12572        if (affect_execstate)
12573            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
12574        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
12575        if (privileged)
12576            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
12577    }
12578
12579    if (BitIsSet (bytemask, 0))
12580    {
12581        if (privileged)
12582            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
12583        if (affect_execstate)
12584            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
12585        if (privileged)
12586            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
12587    }
12588
12589    m_opcode_cpsr = tmp_cpsr;
12590}
12591
12592
12593bool
12594EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
12595{
12596    addr_t target;
12597
12598    // Check the current instruction set.
12599    if (CurrentInstrSet() == eModeARM)
12600        target = addr & 0xfffffffc;
12601    else
12602        target = addr & 0xfffffffe;
12603
12604    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12605        return false;
12606
12607    return true;
12608}
12609
12610// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
12611bool
12612EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
12613{
12614    addr_t target;
12615    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
12616    // we want to record it and issue a WriteRegister callback so the clients
12617    // can track the mode changes accordingly.
12618    bool cpsr_changed = false;
12619
12620    if (BitIsSet(addr, 0))
12621    {
12622        if (CurrentInstrSet() != eModeThumb)
12623        {
12624            SelectInstrSet(eModeThumb);
12625            cpsr_changed = true;
12626        }
12627        target = addr & 0xfffffffe;
12628        context.SetMode (eModeThumb);
12629    }
12630    else if (BitIsClear(addr, 1))
12631    {
12632        if (CurrentInstrSet() != eModeARM)
12633        {
12634            SelectInstrSet(eModeARM);
12635            cpsr_changed = true;
12636        }
12637        target = addr & 0xfffffffc;
12638        context.SetMode (eModeARM);
12639    }
12640    else
12641        return false; // address<1:0> == '10' => UNPREDICTABLE
12642
12643    if (cpsr_changed)
12644    {
12645        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
12646            return false;
12647    }
12648    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12649        return false;
12650
12651    return true;
12652}
12653
12654// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
12655bool
12656EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
12657{
12658    if (ArchVersion() >= ARMv5T)
12659        return BXWritePC(context, addr);
12660    else
12661        return BranchWritePC((const Context)context, addr);
12662}
12663
12664// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
12665bool
12666EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
12667{
12668    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
12669        return BXWritePC(context, addr);
12670    else
12671        return BranchWritePC((const Context)context, addr);
12672}
12673
12674EmulateInstructionARM::Mode
12675EmulateInstructionARM::CurrentInstrSet ()
12676{
12677    return m_opcode_mode;
12678}
12679
12680// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
12681// ReadInstruction() is performed.  This function has a side effect of updating
12682// the m_new_inst_cpsr member variable if necessary.
12683bool
12684EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
12685{
12686    m_new_inst_cpsr = m_opcode_cpsr;
12687    switch (arm_or_thumb)
12688    {
12689    default:
12690        return false;
12691    eModeARM:
12692        // Clear the T bit.
12693        m_new_inst_cpsr &= ~MASK_CPSR_T;
12694        break;
12695    eModeThumb:
12696        // Set the T bit.
12697        m_new_inst_cpsr |= MASK_CPSR_T;
12698        break;
12699    }
12700    return true;
12701}
12702
12703// This function returns TRUE if the processor currently provides support for
12704// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
12705// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
12706bool
12707EmulateInstructionARM::UnalignedSupport()
12708{
12709    return (ArchVersion() >= ARMv7);
12710}
12711
12712// The main addition and subtraction instructions can produce status information
12713// about both unsigned carry and signed overflow conditions.  This status
12714// information can be used to synthesize multi-word additions and subtractions.
12715EmulateInstructionARM::AddWithCarryResult
12716EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
12717{
12718    uint32_t result;
12719    uint8_t carry_out;
12720    uint8_t overflow;
12721
12722    uint64_t unsigned_sum = x + y + carry_in;
12723    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
12724
12725    result = UnsignedBits(unsigned_sum, 31, 0);
12726    carry_out = (result == unsigned_sum ? 0 : 1);
12727    overflow = ((int32_t)result == signed_sum ? 0 : 1);
12728
12729    AddWithCarryResult res = { result, carry_out, overflow };
12730    return res;
12731}
12732
12733uint32_t
12734EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
12735{
12736    uint32_t reg_kind, reg_num;
12737    switch (num)
12738    {
12739    case SP_REG:
12740        reg_kind = eRegisterKindGeneric;
12741        reg_num  = LLDB_REGNUM_GENERIC_SP;
12742        break;
12743    case LR_REG:
12744        reg_kind = eRegisterKindGeneric;
12745        reg_num  = LLDB_REGNUM_GENERIC_RA;
12746        break;
12747    case PC_REG:
12748        reg_kind = eRegisterKindGeneric;
12749        reg_num  = LLDB_REGNUM_GENERIC_PC;
12750        break;
12751    default:
12752        if (num < SP_REG)
12753        {
12754            reg_kind = eRegisterKindDWARF;
12755            reg_num  = dwarf_r0 + num;
12756        }
12757        else
12758        {
12759            assert(0 && "Invalid register number");
12760            *success = false;
12761            return UINT32_MAX;
12762        }
12763        break;
12764    }
12765
12766    // Read our register.
12767    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
12768
12769    // When executing an ARM instruction , PC reads as the address of the current
12770    // instruction plus 8.
12771    // When executing a Thumb instruction , PC reads as the address of the current
12772    // instruction plus 4.
12773    if (num == 15)
12774    {
12775        if (CurrentInstrSet() == eModeARM)
12776            val += 8;
12777        else
12778            val += 4;
12779    }
12780
12781    return val;
12782}
12783
12784// Write the result to the ARM core register Rd, and optionally update the
12785// condition flags based on the result.
12786//
12787// This helper method tries to encapsulate the following pseudocode from the
12788// ARM Architecture Reference Manual:
12789//
12790// if d == 15 then         // Can only occur for encoding A1
12791//     ALUWritePC(result); // setflags is always FALSE here
12792// else
12793//     R[d] = result;
12794//     if setflags then
12795//         APSR.N = result<31>;
12796//         APSR.Z = IsZeroBit(result);
12797//         APSR.C = carry;
12798//         // APSR.V unchanged
12799//
12800// In the above case, the API client does not pass in the overflow arg, which
12801// defaults to ~0u.
12802bool
12803EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
12804                                                  const uint32_t result,
12805                                                  const uint32_t Rd,
12806                                                  bool setflags,
12807                                                  const uint32_t carry,
12808                                                  const uint32_t overflow)
12809{
12810    if (Rd == 15)
12811    {
12812        if (!ALUWritePC (context, result))
12813            return false;
12814    }
12815    else
12816    {
12817        uint32_t reg_kind, reg_num;
12818        switch (Rd)
12819        {
12820        case SP_REG:
12821            reg_kind = eRegisterKindGeneric;
12822            reg_num  = LLDB_REGNUM_GENERIC_SP;
12823            break;
12824        case LR_REG:
12825            reg_kind = eRegisterKindGeneric;
12826            reg_num  = LLDB_REGNUM_GENERIC_RA;
12827            break;
12828        default:
12829            reg_kind = eRegisterKindDWARF;
12830            reg_num  = dwarf_r0 + Rd;
12831        }
12832        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
12833            return false;
12834        if (setflags)
12835            return WriteFlags (context, result, carry, overflow);
12836    }
12837    return true;
12838}
12839
12840// This helper method tries to encapsulate the following pseudocode from the
12841// ARM Architecture Reference Manual:
12842//
12843// APSR.N = result<31>;
12844// APSR.Z = IsZeroBit(result);
12845// APSR.C = carry;
12846// APSR.V = overflow
12847//
12848// Default arguments can be specified for carry and overflow parameters, which means
12849// not to update the respective flags.
12850bool
12851EmulateInstructionARM::WriteFlags (Context &context,
12852                                   const uint32_t result,
12853                                   const uint32_t carry,
12854                                   const uint32_t overflow)
12855{
12856    m_new_inst_cpsr = m_opcode_cpsr;
12857    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
12858    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
12859    if (carry != ~0u)
12860        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
12861    if (overflow != ~0u)
12862        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
12863    if (m_new_inst_cpsr != m_opcode_cpsr)
12864    {
12865        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
12866            return false;
12867    }
12868    return true;
12869}
12870
12871bool
12872EmulateInstructionARM::EvaluateInstruction ()
12873{
12874    // Advance the ITSTATE bits to their values for the next instruction.
12875    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
12876        m_it_session.ITAdvance();
12877
12878    return false;
12879}
12880