EmulateInstructionARM.cpp revision 4d729c559d039181f250e0e3cd444fa73638f26f
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//----------------------------------------------------------------------
27//
28// ITSession implementation
29//
30//----------------------------------------------------------------------
31
32// A8.6.50
33// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
34static unsigned short CountITSize(unsigned ITMask) {
35    // First count the trailing zeros of the IT mask.
36    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
37    if (TZ > 3)
38    {
39        printf("Encoding error: IT Mask '0000'\n");
40        return 0;
41    }
42    return (4 - TZ);
43}
44
45// Init ITState.  Note that at least one bit is always 1 in mask.
46bool ITSession::InitIT(unsigned short bits7_0)
47{
48    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
49    if (ITCounter == 0)
50        return false;
51
52    // A8.6.50 IT
53    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
54    if (FirstCond == 0xF)
55    {
56        printf("Encoding error: IT FirstCond '1111'\n");
57        return false;
58    }
59    if (FirstCond == 0xE && ITCounter != 1)
60    {
61        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
62        return false;
63    }
64
65    ITState = bits7_0;
66    return true;
67}
68
69// Update ITState if necessary.
70void ITSession::ITAdvance()
71{
72    assert(ITCounter);
73    --ITCounter;
74    if (ITCounter == 0)
75        ITState = 0;
76    else
77    {
78        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
79        SetBits32(ITState, 4, 0, NewITState4_0);
80    }
81}
82
83// Return true if we're inside an IT Block.
84bool ITSession::InITBlock()
85{
86    return ITCounter != 0;
87}
88
89// Return true if we're the last instruction inside an IT Block.
90bool ITSession::LastInITBlock()
91{
92    return ITCounter == 1;
93}
94
95// Get condition bits for the current thumb instruction.
96uint32_t ITSession::GetCond()
97{
98    if (InITBlock())
99        return Bits32(ITState, 7, 4);
100    else
101        return COND_AL;
102}
103
104// ARM constants used during decoding
105#define REG_RD          0
106#define LDM_REGLIST     1
107#define PC_REG          15
108#define PC_REGLIST_BIT  0x8000
109
110#define ARMv4     (1u << 0)
111#define ARMv4T    (1u << 1)
112#define ARMv5T    (1u << 2)
113#define ARMv5TE   (1u << 3)
114#define ARMv5TEJ  (1u << 4)
115#define ARMv6     (1u << 5)
116#define ARMv6K    (1u << 6)
117#define ARMv6T2   (1u << 7)
118#define ARMv7     (1u << 8)
119#define ARMv8     (1u << 9)
120#define ARMvAll   (0xffffffffu)
121
122#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
123#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
124#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
125
126//----------------------------------------------------------------------
127//
128// EmulateInstructionARM implementation
129//
130//----------------------------------------------------------------------
131
132void
133EmulateInstructionARM::Initialize ()
134{
135}
136
137void
138EmulateInstructionARM::Terminate ()
139{
140}
141
142// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
143bool
144EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
145{
146    EmulateInstruction::Context context;
147    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
148    context.SetNoArgs ();
149
150    uint32_t random_data = rand ();
151    const uint32_t addr_byte_size = GetAddressByteSize();
152
153    if (!MemAWrite (context, address, random_data, addr_byte_size))
154        return false;
155
156    return true;
157}
158
159// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
160bool
161EmulateInstructionARM::WriteBits32Unknown (int n)
162{
163    EmulateInstruction::Context context;
164    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
165    context.SetNoArgs ();
166
167    bool success;
168    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
169
170    if (!success)
171        return false;
172
173    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
174        return false;
175
176    return true;
177}
178
179// Push Multiple Registers stores multiple registers to the stack, storing to
180// consecutive memory locations ending just below the address in SP, and updates
181// SP to point to the start of the stored data.
182bool
183EmulateInstructionARM::EmulatePUSH (ARMEncoding encoding)
184{
185#if 0
186    // ARM pseudo code...
187    if (ConditionPassed())
188    {
189        EncodingSpecificOperations();
190        NullCheckIfThumbEE(13);
191        address = SP - 4*BitCount(registers);
192
193        for (i = 0 to 14)
194        {
195            if (registers<i> == ’1’)
196            {
197                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
198                    MemA[address,4] = bits(32) UNKNOWN;
199                else
200                    MemA[address,4] = R[i];
201                address = address + 4;
202            }
203        }
204
205        if (registers<15> == ’1’) // Only possible for encoding A1 or A2
206            MemA[address,4] = PCStoreValue();
207
208        SP = SP - 4*BitCount(registers);
209    }
210#endif
211
212    bool success = false;
213    const uint32_t opcode = OpcodeAsUnsigned (&success);
214    if (!success)
215        return false;
216
217    if (ConditionPassed())
218    {
219        const uint32_t addr_byte_size = GetAddressByteSize();
220        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
221        if (!success)
222            return false;
223        uint32_t registers = 0;
224        uint32_t Rt; // the source register
225        switch (encoding) {
226        case eEncodingT1:
227            registers = Bits32(opcode, 7, 0);
228            // The M bit represents LR.
229            if (Bit32(opcode, 8))
230                registers |= (1u << 14);
231            // if BitCount(registers) < 1 then UNPREDICTABLE;
232            if (BitCount(registers) < 1)
233                return false;
234            break;
235        case eEncodingT2:
236            // Ignore bits 15 & 13.
237            registers = Bits32(opcode, 15, 0) & ~0xa000;
238            // if BitCount(registers) < 2 then UNPREDICTABLE;
239            if (BitCount(registers) < 2)
240                return false;
241            break;
242        case eEncodingT3:
243            Rt = Bits32(opcode, 15, 12);
244            // if BadReg(t) then UNPREDICTABLE;
245            if (BadReg(Rt))
246                return false;
247            registers = (1u << Rt);
248            break;
249        case eEncodingA1:
250            registers = Bits32(opcode, 15, 0);
251            // Instead of return false, let's handle the following case as well,
252            // which amounts to pushing one reg onto the full descending stacks.
253            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
254            break;
255        case eEncodingA2:
256            Rt = Bits32(opcode, 15, 12);
257            // if t == 13 then UNPREDICTABLE;
258            if (Rt == dwarf_sp)
259                return false;
260            registers = (1u << Rt);
261            break;
262        default:
263            return false;
264        }
265        addr_t sp_offset = addr_byte_size * BitCount (registers);
266        addr_t addr = sp - sp_offset;
267        uint32_t i;
268
269        EmulateInstruction::Context context;
270        context.type = EmulateInstruction::eContextPushRegisterOnStack;
271        Register dwarf_reg;
272        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
273        for (i=0; i<15; ++i)
274        {
275            if (BitIsSet (registers, i))
276            {
277                dwarf_reg.num = dwarf_r0 + i;
278                context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
279                uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
280                if (!success)
281                    return false;
282                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
283                    return false;
284                addr += addr_byte_size;
285            }
286        }
287
288        if (BitIsSet (registers, 15))
289        {
290            dwarf_reg.num = dwarf_pc;
291            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
292            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
293            if (!success)
294                return false;
295            if (!MemAWrite (context, addr, pc + 8, addr_byte_size))
296                return false;
297        }
298
299        context.type = EmulateInstruction::eContextAdjustStackPointer;
300        context.SetImmediateSigned (-sp_offset);
301
302        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
303            return false;
304    }
305    return true;
306}
307
308// Pop Multiple Registers loads multiple registers from the stack, loading from
309// consecutive memory locations staring at the address in SP, and updates
310// SP to point just above the loaded data.
311bool
312EmulateInstructionARM::EmulatePOP (ARMEncoding encoding)
313{
314#if 0
315    // ARM pseudo code...
316    if (ConditionPassed())
317    {
318        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
319        address = SP;
320        for i = 0 to 14
321            if registers<i> == ‘1then
322                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
323        if registers<15> == ‘1then
324            if UnalignedAllowed then
325                LoadWritePC(MemU[address,4]);
326            else
327                LoadWritePC(MemA[address,4]);
328        if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers);
329        if registers<13> == ‘1then SP = bits(32) UNKNOWN;
330    }
331#endif
332
333    bool success = false;
334    const uint32_t opcode = OpcodeAsUnsigned (&success);
335    if (!success)
336        return false;
337
338    if (ConditionPassed())
339    {
340        const uint32_t addr_byte_size = GetAddressByteSize();
341        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
342        if (!success)
343            return false;
344        uint32_t registers = 0;
345        uint32_t Rt; // the destination register
346        switch (encoding) {
347        case eEncodingT1:
348            registers = Bits32(opcode, 7, 0);
349            // The P bit represents PC.
350            if (Bit32(opcode, 8))
351                registers |= (1u << 15);
352            // if BitCount(registers) < 1 then UNPREDICTABLE;
353            if (BitCount(registers) < 1)
354                return false;
355            break;
356        case eEncodingT2:
357            // Ignore bit 13.
358            registers = Bits32(opcode, 15, 0) & ~0x2000;
359            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
360            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
361                return false;
362            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
363            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
364                return false;
365            break;
366        case eEncodingT3:
367            Rt = Bits32(opcode, 15, 12);
368            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
369            if (Rt == 13)
370                return false;
371            if (Rt == 15 && InITBlock() && !LastInITBlock())
372                return false;
373            registers = (1u << Rt);
374            break;
375        case eEncodingA1:
376            registers = Bits32(opcode, 15, 0);
377            // Instead of return false, let's handle the following case as well,
378            // which amounts to popping one reg from the full descending stacks.
379            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
380
381            // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE;
382            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
383                return false;
384            break;
385        case eEncodingA2:
386            Rt = Bits32(opcode, 15, 12);
387            // if t == 13 then UNPREDICTABLE;
388            if (Rt == dwarf_sp)
389                return false;
390            registers = (1u << Rt);
391            break;
392        default:
393            return false;
394        }
395        addr_t sp_offset = addr_byte_size * BitCount (registers);
396        addr_t addr = sp;
397        uint32_t i, data;
398
399        EmulateInstruction::Context context;
400        context.type = EmulateInstruction::eContextPopRegisterOffStack;
401        Register dwarf_reg;
402        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
403        for (i=0; i<15; ++i)
404        {
405            if (BitIsSet (registers, i))
406            {
407                dwarf_reg.num = dwarf_r0 + i;
408                context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
409                data = MemARead(context, addr, 4, 0, &success);
410                if (!success)
411                    return false;
412                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
413                    return false;
414                addr += addr_byte_size;
415            }
416        }
417
418        if (BitIsSet (registers, 15))
419        {
420            dwarf_reg.num = dwarf_pc;
421            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
422            data = MemARead(context, addr, 4, 0, &success);
423            if (!success)
424                return false;
425            // In ARMv5T and above, this is an interworking branch.
426            if (!LoadWritePC(context, data))
427                return false;
428            addr += addr_byte_size;
429        }
430
431        context.type = EmulateInstruction::eContextAdjustStackPointer;
432        context.SetImmediateSigned (sp_offset);
433
434        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
435            return false;
436    }
437    return true;
438}
439
440// Set r7 or ip to point to saved value residing within the stack.
441// ADD (SP plus immediate)
442bool
443EmulateInstructionARM::EmulateADDRdSPImm (ARMEncoding encoding)
444{
445#if 0
446    // ARM pseudo code...
447    if (ConditionPassed())
448    {
449        EncodingSpecificOperations();
450        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
451        if d == 15 then
452           ALUWritePC(result); // setflags is always FALSE here
453        else
454            R[d] = result;
455            if setflags then
456                APSR.N = result<31>;
457                APSR.Z = IsZeroBit(result);
458                APSR.C = carry;
459                APSR.V = overflow;
460    }
461#endif
462
463    bool success = false;
464    const uint32_t opcode = OpcodeAsUnsigned (&success);
465    if (!success)
466        return false;
467
468    if (ConditionPassed())
469    {
470        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
471        if (!success)
472            return false;
473        uint32_t Rd; // the destination register
474        uint32_t imm32;
475        switch (encoding) {
476        case eEncodingT1:
477            Rd = 7;
478            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
479            break;
480        case eEncodingA1:
481            Rd = Bits32(opcode, 15, 12);
482            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
483            break;
484        default:
485            return false;
486        }
487        addr_t sp_offset = imm32;
488        addr_t addr = sp + sp_offset; // a pointer to the stack area
489
490        EmulateInstruction::Context context;
491        context.type = EmulateInstruction::eContextRegisterPlusOffset;
492        Register sp_reg;
493        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
494        context.SetRegisterPlusOffset (sp_reg, sp_offset);
495
496        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
497            return false;
498    }
499    return true;
500}
501
502// Set r7 or ip to the current stack pointer.
503// MOV (register)
504bool
505EmulateInstructionARM::EmulateMOVRdSP (ARMEncoding encoding)
506{
507#if 0
508    // ARM pseudo code...
509    if (ConditionPassed())
510    {
511        EncodingSpecificOperations();
512        result = R[m];
513        if d == 15 then
514            ALUWritePC(result); // setflags is always FALSE here
515        else
516            R[d] = result;
517            if setflags then
518                APSR.N = result<31>;
519                APSR.Z = IsZeroBit(result);
520                // APSR.C unchanged
521                // APSR.V unchanged
522    }
523#endif
524
525    bool success = false;
526    //const uint32_t opcode = OpcodeAsUnsigned (&success);
527    //if (!success)
528    //    return false;
529
530    if (ConditionPassed())
531    {
532        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
533        if (!success)
534            return false;
535        uint32_t Rd; // the destination register
536        switch (encoding) {
537        case eEncodingT1:
538            Rd = 7;
539            break;
540        case eEncodingA1:
541            Rd = 12;
542            break;
543        default:
544            return false;
545        }
546
547        EmulateInstruction::Context context;
548        context.type = EmulateInstruction::eContextRegisterPlusOffset;
549        Register sp_reg;
550        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
551        context.SetRegisterPlusOffset (sp_reg, 0);
552
553        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
554            return false;
555    }
556    return true;
557}
558
559// Move from high register (r8-r15) to low register (r0-r7).
560// MOV (register)
561bool
562EmulateInstructionARM::EmulateMOVLowHigh (ARMEncoding encoding)
563{
564    return EmulateMOVRdRm (encoding);
565}
566
567// Move from register to register.
568// MOV (register)
569bool
570EmulateInstructionARM::EmulateMOVRdRm (ARMEncoding encoding)
571{
572#if 0
573    // ARM pseudo code...
574    if (ConditionPassed())
575    {
576        EncodingSpecificOperations();
577        result = R[m];
578        if d == 15 then
579            ALUWritePC(result); // setflags is always FALSE here
580        else
581            R[d] = result;
582            if setflags then
583                APSR.N = result<31>;
584                APSR.Z = IsZeroBit(result);
585                // APSR.C unchanged
586                // APSR.V unchanged
587    }
588#endif
589
590    bool success = false;
591    const uint32_t opcode = OpcodeAsUnsigned (&success);
592    if (!success)
593        return false;
594
595    if (ConditionPassed())
596    {
597        uint32_t Rm; // the source register
598        uint32_t Rd; // the destination register
599        bool setflags;
600        switch (encoding) {
601        case eEncodingT1:
602            Rm = Bits32(opcode, 6, 3);
603            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1);
604            setflags = false;
605            break;
606        case eEncodingT2:
607            Rm = Bits32(opcode, 5, 3);
608            Rd = Bits32(opcode, 2, 1);
609            setflags = true;
610            break;
611        default:
612            return false;
613        }
614        uint32_t result = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
615        if (!success)
616            return false;
617
618        // The context specifies that Rm is to be moved into Rd.
619        EmulateInstruction::Context context;
620        context.type = EmulateInstruction::eContextRegisterPlusOffset;
621        Register dwarf_reg;
622        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
623        context.SetRegisterPlusOffset (dwarf_reg, 0);
624
625        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
626            return false;
627    }
628    return true;
629}
630
631// Move (immediate) writes an immediate value to the destination register.  It
632// can optionally update the condition flags based on the value.
633// MOV (immediate)
634bool
635EmulateInstructionARM::EmulateMOVRdImm (ARMEncoding encoding)
636{
637#if 0
638    // ARM pseudo code...
639    if (ConditionPassed())
640    {
641        EncodingSpecificOperations();
642        result = imm32;
643        if d == 15 then         // Can only occur for ARM encoding
644            ALUWritePC(result); // setflags is always FALSE here
645        else
646            R[d] = result;
647            if setflags then
648                APSR.N = result<31>;
649                APSR.Z = IsZeroBit(result);
650                APSR.C = carry;
651                // APSR.V unchanged
652    }
653#endif
654    bool success = false;
655    const uint32_t opcode = OpcodeAsUnsigned (&success);
656    if (!success)
657        return false;
658
659    if (ConditionPassed())
660    {
661        uint32_t Rd; // the destination register
662        uint32_t imm12; // some intermediate result
663        uint32_t imm32; // the immediate value to be written to Rd
664        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
665        bool setflags;
666        switch (encoding) {
667        case eEncodingT1:
668            Rd = Bits32(opcode, 11, 8);
669            setflags = !InITBlock();
670            imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
671            carry = Bit32(m_inst_cpsr, CPSR_C);
672            break;
673        case eEncodingT2:
674            Rd = Bits32(opcode, 15, 12);
675            setflags = BitIsSet(opcode, 20);
676            imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0);
677            imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry);
678            if (BadReg(Rd))
679                return false;
680            break;
681        default:
682            return false;
683        }
684        uint32_t result = imm32;
685
686        // The context specifies that an immediate is to be moved into Rd.
687        EmulateInstruction::Context context;
688        context.type = EmulateInstruction::eContextImmediate;
689        context.SetNoArgs ();
690
691        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
692            return false;
693    }
694    return true;
695}
696
697// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
698// the destination register.  It can optionally update the condition flags based
699// on the value.
700// MVN (immediate)
701bool
702EmulateInstructionARM::EmulateMVNRdImm (ARMEncoding encoding)
703{
704#if 0
705    // ARM pseudo code...
706    if (ConditionPassed())
707    {
708        EncodingSpecificOperations();
709        result = NOT(imm32);
710        if d == 15 then         // Can only occur for ARM encoding
711            ALUWritePC(result); // setflags is always FALSE here
712        else
713            R[d] = result;
714            if setflags then
715                APSR.N = result<31>;
716                APSR.Z = IsZeroBit(result);
717                APSR.C = carry;
718                // APSR.V unchanged
719    }
720#endif
721    bool success = false;
722    const uint32_t opcode = OpcodeAsUnsigned (&success);
723    if (!success)
724        return false;
725
726    if (ConditionPassed())
727    {
728        uint32_t Rd; // the destination register
729        uint32_t imm12; // the first operand to ThumbExpandImm_C or ARMExpandImm_C
730        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
731        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
732        bool setflags;
733        switch (encoding) {
734        case eEncodingT1:
735            Rd = Bits32(opcode, 11, 8);
736            setflags = BitIsSet(opcode, 20);
737            imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0);
738            imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry);
739            break;
740        case eEncodingA1:
741            Rd = Bits32(opcode, 15, 12);
742            setflags = BitIsSet(opcode, 20);
743            imm12 = Bits32(opcode, 11, 0);
744            imm32 = ARMExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry);
745            break;
746        default:
747            return false;
748        }
749        uint32_t result = ~imm32;
750
751        // The context specifies that an immediate is to be moved into Rd.
752        EmulateInstruction::Context context;
753        context.type = EmulateInstruction::eContextImmediate;
754        context.SetNoArgs ();
755
756        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
757            return false;
758    }
759    return true;
760}
761
762// PC relative immediate load into register, possibly followed by ADD (SP plus register).
763// LDR (literal)
764bool
765EmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding)
766{
767#if 0
768    // ARM pseudo code...
769    if (ConditionPassed())
770    {
771        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
772        base = Align(PC,4);
773        address = if add then (base + imm32) else (base - imm32);
774        data = MemU[address,4];
775        if t == 15 then
776            if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE;
777        elsif UnalignedSupport() || address<1:0> = ‘00’ then
778            R[t] = data;
779        else // Can only apply before ARMv7
780            if CurrentInstrSet() == InstrSet_ARM then
781                R[t] = ROR(data, 8*UInt(address<1:0>));
782            else
783                R[t] = bits(32) UNKNOWN;
784    }
785#endif
786
787    bool success = false;
788    const uint32_t opcode = OpcodeAsUnsigned (&success);
789    if (!success)
790        return false;
791
792    if (ConditionPassed())
793    {
794        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
795        if (!success)
796            return false;
797
798        // PC relative immediate load context
799        EmulateInstruction::Context context;
800        context.type = EmulateInstruction::eContextRegisterPlusOffset;
801        Register pc_reg;
802        pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
803        context.SetRegisterPlusOffset (pc_reg, 0);
804
805        uint32_t Rt;    // the destination register
806        uint32_t imm32; // immediate offset from the PC
807        bool add;       // +imm32 or -imm32?
808        addr_t base;    // the base address
809        addr_t address; // the PC relative address
810        uint32_t data;  // the literal data value from the PC relative load
811        switch (encoding) {
812        case eEncodingT1:
813            Rt = Bits32(opcode, 10, 8);
814            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
815            add = true;
816            base = Align(pc + 4, 4);
817            context.SetRegisterPlusOffset (pc_reg, 4 + imm32);
818            break;
819        case eEncodingT2:
820            Rt = Bits32(opcode, 15, 12);
821            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
822            add = BitIsSet(opcode, 23);
823            if (Rt == 15 && InITBlock() && !LastInITBlock())
824                return false;
825            base = Align(pc + 4, 4);
826            context.SetRegisterPlusOffset (pc_reg, 4 + imm32);
827            break;
828        default:
829            return false;
830        }
831
832        if (add)
833            address = base + imm32;
834        else
835            address = base - imm32;
836        data = MemURead(context, address, 4, 0, &success);
837        if (!success)
838            return false;
839
840        if (Rt == 15)
841        {
842            if (Bits32(address, 1, 0) == 0)
843            {
844                // In ARMv5T and above, this is an interworking branch.
845                if (!LoadWritePC(context, data))
846                    return false;
847            }
848            else
849                return false;
850        }
851        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
852        {
853            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
854                return false;
855        }
856        else // We don't handle ARM for now.
857            return false;
858
859        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
860            return false;
861    }
862    return true;
863}
864
865// An add operation to adjust the SP.
866// ADD (SP plus immediate)
867bool
868EmulateInstructionARM::EmulateADDSPImm (ARMEncoding encoding)
869{
870#if 0
871    // ARM pseudo code...
872    if (ConditionPassed())
873    {
874        EncodingSpecificOperations();
875        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
876        if d == 15 then // Can only occur for ARM encoding
877            ALUWritePC(result); // setflags is always FALSE here
878        else
879            R[d] = result;
880            if setflags then
881                APSR.N = result<31>;
882                APSR.Z = IsZeroBit(result);
883                APSR.C = carry;
884                APSR.V = overflow;
885    }
886#endif
887
888    bool success = false;
889    const uint32_t opcode = OpcodeAsUnsigned (&success);
890    if (!success)
891        return false;
892
893    if (ConditionPassed())
894    {
895        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
896        if (!success)
897            return false;
898        uint32_t imm32; // the immediate operand
899        switch (encoding) {
900        case eEncodingT2:
901            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
902            break;
903        default:
904            return false;
905        }
906        addr_t sp_offset = imm32;
907        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
908
909        EmulateInstruction::Context context;
910        context.type = EmulateInstruction::eContextAdjustStackPointer;
911        context.SetImmediateSigned (sp_offset);
912
913        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
914            return false;
915    }
916    return true;
917}
918
919// An add operation to adjust the SP.
920// ADD (SP plus register)
921bool
922EmulateInstructionARM::EmulateADDSPRm (ARMEncoding encoding)
923{
924#if 0
925    // ARM pseudo code...
926    if (ConditionPassed())
927    {
928        EncodingSpecificOperations();
929        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
930        (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’);
931        if d == 15 then
932            ALUWritePC(result); // setflags is always FALSE here
933        else
934            R[d] = result;
935            if setflags then
936                APSR.N = result<31>;
937                APSR.Z = IsZeroBit(result);
938                APSR.C = carry;
939                APSR.V = overflow;
940    }
941#endif
942
943    bool success = false;
944    const uint32_t opcode = OpcodeAsUnsigned (&success);
945    if (!success)
946        return false;
947
948    if (ConditionPassed())
949    {
950        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
951        if (!success)
952            return false;
953        uint32_t Rm; // the second operand
954        switch (encoding) {
955        case eEncodingT2:
956            Rm = Bits32(opcode, 6, 3);
957            break;
958        default:
959            return false;
960        }
961        int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
962        if (!success)
963            return false;
964
965        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
966
967        EmulateInstruction::Context context;
968        context.type = EmulateInstruction::eContextAdjustStackPointer;
969        context.SetImmediateSigned (reg_value);
970
971        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
972            return false;
973    }
974    return true;
975}
976
977// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
978// at a PC-relative address, and changes instruction set from ARM to Thumb, or
979// from Thumb to ARM.
980// BLX (immediate)
981bool
982EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding)
983{
984#if 0
985    // ARM pseudo code...
986    if (ConditionPassed())
987    {
988        EncodingSpecificOperations();
989        if CurrentInstrSet() == InstrSet_ARM then
990            LR = PC - 4;
991        else
992            LR = PC<31:1> : '1';
993        if targetInstrSet == InstrSet_ARM then
994            targetAddress = Align(PC,4) + imm32;
995        else
996            targetAddress = PC + imm32;
997        SelectInstrSet(targetInstrSet);
998        BranchWritePC(targetAddress);
999    }
1000#endif
1001
1002    bool success = false;
1003    const uint32_t opcode = OpcodeAsUnsigned (&success);
1004    if (!success)
1005        return false;
1006
1007    if (ConditionPassed())
1008    {
1009        EmulateInstruction::Context context;
1010        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1011        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1012        if (!success)
1013            return false;
1014        addr_t lr; // next instruction address
1015        addr_t target; // target address
1016        int32_t imm32; // PC-relative offset
1017        switch (encoding) {
1018        case eEncodingT1:
1019            {
1020            lr = (pc + 4) | 1u; // return address
1021            uint32_t S = Bit32(opcode, 26);
1022            uint32_t imm10 = Bits32(opcode, 25, 16);
1023            uint32_t J1 = Bit32(opcode, 13);
1024            uint32_t J2 = Bit32(opcode, 11);
1025            uint32_t imm11 = Bits32(opcode, 10, 0);
1026            uint32_t I1 = !(J1 ^ S);
1027            uint32_t I2 = !(J2 ^ S);
1028            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1029            imm32 = llvm::SignExtend32<25>(imm25);
1030            target = pc + 4 + imm32;
1031            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1032            if (InITBlock() && !LastInITBlock())
1033                return false;
1034            break;
1035            }
1036        case eEncodingT2:
1037            {
1038            lr = (pc + 4) | 1u; // return address
1039            uint32_t S = Bit32(opcode, 26);
1040            uint32_t imm10H = Bits32(opcode, 25, 16);
1041            uint32_t J1 = Bit32(opcode, 13);
1042            uint32_t J2 = Bit32(opcode, 11);
1043            uint32_t imm10L = Bits32(opcode, 10, 1);
1044            uint32_t I1 = !(J1 ^ S);
1045            uint32_t I2 = !(J2 ^ S);
1046            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1047            imm32 = llvm::SignExtend32<25>(imm25);
1048            target = Align(pc + 4, 4) + imm32;
1049            context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1050            if (InITBlock() && !LastInITBlock())
1051                return false;
1052            break;
1053            }
1054        case eEncodingA1:
1055            lr = pc + 4; // return address
1056            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1057            target = Align(pc + 8, 4) + imm32;
1058            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1059            break;
1060        case eEncodingA2:
1061            lr = pc + 4; // return address
1062            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1063            target = pc + 8 + imm32;
1064            context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
1065            break;
1066        default:
1067            return false;
1068        }
1069        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1070            return false;
1071        if (!BranchWritePC(context, target))
1072            return false;
1073    }
1074    return true;
1075}
1076
1077// Branch with Link and Exchange (register) calls a subroutine at an address and
1078// instruction set specified by a register.
1079// BLX (register)
1080bool
1081EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding)
1082{
1083#if 0
1084    // ARM pseudo code...
1085    if (ConditionPassed())
1086    {
1087        EncodingSpecificOperations();
1088        target = R[m];
1089        if CurrentInstrSet() == InstrSet_ARM then
1090            next_instr_addr = PC - 4;
1091            LR = next_instr_addr;
1092        else
1093            next_instr_addr = PC - 2;
1094            LR = next_instr_addr<31:1> : ‘1’;
1095        BXWritePC(target);
1096    }
1097#endif
1098
1099    bool success = false;
1100    const uint32_t opcode = OpcodeAsUnsigned (&success);
1101    if (!success)
1102        return false;
1103
1104    if (ConditionPassed())
1105    {
1106        EmulateInstruction::Context context;
1107        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1108        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1109        addr_t lr; // next instruction address
1110        if (!success)
1111            return false;
1112        uint32_t Rm; // the register with the target address
1113        switch (encoding) {
1114        case eEncodingT1:
1115            lr = (pc + 2) | 1u; // return address
1116            Rm = Bits32(opcode, 6, 3);
1117            // if m == 15 then UNPREDICTABLE;
1118            if (Rm == 15)
1119                return false;
1120            if (InITBlock() && !LastInITBlock())
1121                return false;
1122            break;
1123        case eEncodingA1:
1124            lr = pc + 4; // return address
1125            Rm = Bits32(opcode, 3, 0);
1126            // if m == 15 then UNPREDICTABLE;
1127            if (Rm == 15)
1128                return false;
1129            break;
1130        default:
1131            return false;
1132        }
1133        addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1134        if (!success)
1135            return false;
1136        Register dwarf_reg;
1137        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1138        context.SetRegister (dwarf_reg);
1139        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1140            return false;
1141        if (!BXWritePC(context, target))
1142            return false;
1143    }
1144    return true;
1145}
1146
1147// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1148// BX
1149bool
1150EmulateInstructionARM::EmulateBXRm (ARMEncoding encoding)
1151{
1152#if 0
1153    // ARM pseudo code...
1154    if (ConditionPassed())
1155    {
1156        EncodingSpecificOperations();
1157        BXWritePC(R[m]);
1158    }
1159#endif
1160
1161    bool success = false;
1162    const uint32_t opcode = OpcodeAsUnsigned (&success);
1163    if (!success)
1164        return false;
1165
1166    if (ConditionPassed())
1167    {
1168        EmulateInstruction::Context context;
1169        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1170        uint32_t Rm; // the register with the target address
1171        switch (encoding) {
1172        case eEncodingT1:
1173            Rm = Bits32(opcode, 6, 3);
1174            if (InITBlock() && !LastInITBlock())
1175                return false;
1176            break;
1177        case eEncodingA1:
1178            Rm = Bits32(opcode, 3, 0);
1179            break;
1180        default:
1181            return false;
1182        }
1183        addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1184        if (!success)
1185            return false;
1186
1187        Register dwarf_reg;
1188        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1189        context.SetRegister (dwarf_reg);
1190        if (!BXWritePC(context, target))
1191            return false;
1192    }
1193    return true;
1194}
1195
1196// Set r7 to point to some ip offset.
1197// SUB (immediate)
1198bool
1199EmulateInstructionARM::EmulateSUBR7IPImm (ARMEncoding encoding)
1200{
1201#if 0
1202    // ARM pseudo code...
1203    if (ConditionPassed())
1204    {
1205        EncodingSpecificOperations();
1206        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
1207        if d == 15 then // Can only occur for ARM encoding
1208           ALUWritePC(result); // setflags is always FALSE here
1209        else
1210            R[d] = result;
1211            if setflags then
1212                APSR.N = result<31>;
1213                APSR.Z = IsZeroBit(result);
1214                APSR.C = carry;
1215                APSR.V = overflow;
1216    }
1217#endif
1218
1219    bool success = false;
1220    const uint32_t opcode = OpcodeAsUnsigned (&success);
1221    if (!success)
1222        return false;
1223
1224    if (ConditionPassed())
1225    {
1226        const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success);
1227        if (!success)
1228            return false;
1229        uint32_t imm32;
1230        switch (encoding) {
1231        case eEncodingA1:
1232            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1233            break;
1234        default:
1235            return false;
1236        }
1237        addr_t ip_offset = imm32;
1238        addr_t addr = ip - ip_offset; // the adjusted ip value
1239
1240        EmulateInstruction::Context context;
1241        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1242        Register dwarf_reg;
1243        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
1244        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1245
1246        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1247            return false;
1248    }
1249    return true;
1250}
1251
1252// Set ip to point to some stack offset.
1253// SUB (SP minus immediate)
1254bool
1255EmulateInstructionARM::EmulateSUBIPSPImm (ARMEncoding encoding)
1256{
1257#if 0
1258    // ARM pseudo code...
1259    if (ConditionPassed())
1260    {
1261        EncodingSpecificOperations();
1262        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
1263        if d == 15 then // Can only occur for ARM encoding
1264           ALUWritePC(result); // setflags is always FALSE here
1265        else
1266            R[d] = result;
1267            if setflags then
1268                APSR.N = result<31>;
1269                APSR.Z = IsZeroBit(result);
1270                APSR.C = carry;
1271                APSR.V = overflow;
1272    }
1273#endif
1274
1275    bool success = false;
1276    const uint32_t opcode = OpcodeAsUnsigned (&success);
1277    if (!success)
1278        return false;
1279
1280    if (ConditionPassed())
1281    {
1282        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1283        if (!success)
1284            return false;
1285        uint32_t imm32;
1286        switch (encoding) {
1287        case eEncodingA1:
1288            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1289            break;
1290        default:
1291            return false;
1292        }
1293        addr_t sp_offset = imm32;
1294        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1295
1296        EmulateInstruction::Context context;
1297        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1298        Register dwarf_reg;
1299        dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1300        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1301
1302        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1303            return false;
1304    }
1305    return true;
1306}
1307
1308// A sub operation to adjust the SP -- allocate space for local storage.
1309bool
1310EmulateInstructionARM::EmulateSUBSPImm (ARMEncoding encoding)
1311{
1312#if 0
1313    // ARM pseudo code...
1314    if (ConditionPassed())
1315    {
1316        EncodingSpecificOperations();
1317        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
1318        if d == 15 then // Can only occur for ARM encoding
1319           ALUWritePC(result); // setflags is always FALSE here
1320        else
1321            R[d] = result;
1322            if setflags then
1323                APSR.N = result<31>;
1324                APSR.Z = IsZeroBit(result);
1325                APSR.C = carry;
1326                APSR.V = overflow;
1327    }
1328#endif
1329
1330    bool success = false;
1331    const uint32_t opcode = OpcodeAsUnsigned (&success);
1332    if (!success)
1333        return false;
1334
1335    if (ConditionPassed())
1336    {
1337        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1338        if (!success)
1339            return false;
1340        uint32_t imm32;
1341        switch (encoding) {
1342        case eEncodingT1:
1343            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1344        case eEncodingT2:
1345            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1346            break;
1347        case eEncodingT3:
1348            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1349            break;
1350        case eEncodingA1:
1351            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1352            break;
1353        default:
1354            return false;
1355        }
1356        addr_t sp_offset = imm32;
1357        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1358
1359        EmulateInstruction::Context context;
1360        context.type = EmulateInstruction::eContextAdjustStackPointer;
1361        context.SetImmediateSigned (-sp_offset);
1362
1363        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1364            return false;
1365    }
1366    return true;
1367}
1368
1369// A store operation to the stack that also updates the SP.
1370bool
1371EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding)
1372{
1373#if 0
1374    // ARM pseudo code...
1375    if (ConditionPassed())
1376    {
1377        EncodingSpecificOperations();
1378        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1379        address = if index then offset_addr else R[n];
1380        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1381        if wback then R[n] = offset_addr;
1382    }
1383#endif
1384
1385    bool success = false;
1386    const uint32_t opcode = OpcodeAsUnsigned (&success);
1387    if (!success)
1388        return false;
1389
1390    if (ConditionPassed())
1391    {
1392        const uint32_t addr_byte_size = GetAddressByteSize();
1393        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1394        if (!success)
1395            return false;
1396        uint32_t Rt; // the source register
1397        uint32_t imm12;
1398        switch (encoding) {
1399        case eEncodingA1:
1400            Rt = Bits32(opcode, 15, 12);
1401            imm12 = Bits32(opcode, 11, 0);
1402            break;
1403        default:
1404            return false;
1405        }
1406        addr_t sp_offset = imm12;
1407        addr_t addr = sp - sp_offset;
1408
1409        EmulateInstruction::Context context;
1410        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1411        Register dwarf_reg;
1412        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1413        if (Rt != 15)
1414        {
1415            dwarf_reg.num = dwarf_r0 + Rt;
1416            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1417            uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1418            if (!success)
1419                return false;
1420            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1421                return false;
1422        }
1423        else
1424        {
1425            dwarf_reg.num = dwarf_pc;
1426            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1427            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1428            if (!success)
1429                return false;
1430            if (!MemUWrite (context, addr, pc + 8, addr_byte_size))
1431                return false;
1432        }
1433
1434        context.type = EmulateInstruction::eContextAdjustStackPointer;
1435        context.SetImmediateSigned (-sp_offset);
1436
1437        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1438            return false;
1439    }
1440    return true;
1441}
1442
1443// Vector Push stores multiple extension registers to the stack.
1444// It also updates SP to point to the start of the stored data.
1445bool
1446EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding)
1447{
1448#if 0
1449    // ARM pseudo code...
1450    if (ConditionPassed())
1451    {
1452        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1453        address = SP - imm32;
1454        SP = SP - imm32;
1455        if single_regs then
1456            for r = 0 to regs-1
1457                MemA[address,4] = S[d+r]; address = address+4;
1458        else
1459            for r = 0 to regs-1
1460                // Store as two word-aligned words in the correct order for current endianness.
1461                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1462                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1463                address = address+8;
1464    }
1465#endif
1466
1467    bool success = false;
1468    const uint32_t opcode = OpcodeAsUnsigned (&success);
1469    if (!success)
1470        return false;
1471
1472    if (ConditionPassed())
1473    {
1474        const uint32_t addr_byte_size = GetAddressByteSize();
1475        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1476        if (!success)
1477            return false;
1478        bool single_regs;
1479        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1480        uint32_t imm32; // stack offset
1481        uint32_t regs;  // number of registers
1482        switch (encoding) {
1483        case eEncodingT1:
1484        case eEncodingA1:
1485            single_regs = false;
1486            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1487            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1488            // If UInt(imm8) is odd, see "FSTMX".
1489            regs = Bits32(opcode, 7, 0) / 2;
1490            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1491            if (regs == 0 || regs > 16 || (d + regs) > 32)
1492                return false;
1493            break;
1494        case eEncodingT2:
1495        case eEncodingA2:
1496            single_regs = true;
1497            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1498            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1499            regs = Bits32(opcode, 7, 0);
1500            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1501            if (regs == 0 || regs > 16 || (d + regs) > 32)
1502                return false;
1503            break;
1504        default:
1505            return false;
1506        }
1507        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1508        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1509        addr_t sp_offset = imm32;
1510        addr_t addr = sp - sp_offset;
1511        uint32_t i;
1512
1513        EmulateInstruction::Context context;
1514        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1515        Register dwarf_reg;
1516        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1517        for (i=d; i<regs; ++i)
1518        {
1519            dwarf_reg.num = start_reg + i;
1520            context.SetRegisterPlusOffset ( dwarf_reg, addr - sp);
1521            // uint64_t to accommodate 64-bit registers.
1522            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1523            if (!success)
1524                return false;
1525            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1526                return false;
1527            addr += reg_byte_size;
1528        }
1529
1530        context.type = EmulateInstruction::eContextAdjustStackPointer;
1531        context.SetImmediateSigned (-sp_offset);
1532
1533        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1534            return false;
1535    }
1536    return true;
1537}
1538
1539// Vector Pop loads multiple extension registers from the stack.
1540// It also updates SP to point just above the loaded data.
1541bool
1542EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding)
1543{
1544#if 0
1545    // ARM pseudo code...
1546    if (ConditionPassed())
1547    {
1548        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1549        address = SP;
1550        SP = SP + imm32;
1551        if single_regs then
1552            for r = 0 to regs-1
1553                S[d+r] = MemA[address,4]; address = address+4;
1554        else
1555            for r = 0 to regs-1
1556                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1557                // Combine the word-aligned words in the correct order for current endianness.
1558                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1559    }
1560#endif
1561
1562    bool success = false;
1563    const uint32_t opcode = OpcodeAsUnsigned (&success);
1564    if (!success)
1565        return false;
1566
1567    if (ConditionPassed())
1568    {
1569        const uint32_t addr_byte_size = GetAddressByteSize();
1570        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1571        if (!success)
1572            return false;
1573        bool single_regs;
1574        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1575        uint32_t imm32; // stack offset
1576        uint32_t regs;  // number of registers
1577        switch (encoding) {
1578        case eEncodingT1:
1579        case eEncodingA1:
1580            single_regs = false;
1581            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1582            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1583            // If UInt(imm8) is odd, see "FLDMX".
1584            regs = Bits32(opcode, 7, 0) / 2;
1585            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1586            if (regs == 0 || regs > 16 || (d + regs) > 32)
1587                return false;
1588            break;
1589        case eEncodingT2:
1590        case eEncodingA2:
1591            single_regs = true;
1592            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1593            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1594            regs = Bits32(opcode, 7, 0);
1595            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1596            if (regs == 0 || regs > 16 || (d + regs) > 32)
1597                return false;
1598            break;
1599        default:
1600            return false;
1601        }
1602        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1603        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1604        addr_t sp_offset = imm32;
1605        addr_t addr = sp;
1606        uint32_t i;
1607        uint64_t data; // uint64_t to accomodate 64-bit registers.
1608
1609        EmulateInstruction::Context context;
1610        context.type = EmulateInstruction::eContextPopRegisterOffStack;
1611        Register dwarf_reg;
1612        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1613        for (i=d; i<regs; ++i)
1614        {
1615            dwarf_reg.num = start_reg + i;
1616            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1617            data = MemARead(context, addr, reg_byte_size, 0, &success);
1618            if (!success)
1619                return false;
1620            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
1621                return false;
1622            addr += reg_byte_size;
1623        }
1624
1625        context.type = EmulateInstruction::eContextAdjustStackPointer;
1626        context.SetImmediateSigned (sp_offset);
1627
1628        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1629            return false;
1630    }
1631    return true;
1632}
1633
1634// SVC (previously SWI)
1635bool
1636EmulateInstructionARM::EmulateSVC (ARMEncoding encoding)
1637{
1638#if 0
1639    // ARM pseudo code...
1640    if (ConditionPassed())
1641    {
1642        EncodingSpecificOperations();
1643        CallSupervisor();
1644    }
1645#endif
1646
1647    bool success = false;
1648    const uint32_t opcode = OpcodeAsUnsigned (&success);
1649    if (!success)
1650        return false;
1651
1652    if (ConditionPassed())
1653    {
1654        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1655        addr_t lr; // next instruction address
1656        if (!success)
1657            return false;
1658        uint32_t imm32; // the immediate constant
1659        uint32_t mode;  // ARM or Thumb mode
1660        switch (encoding) {
1661        case eEncodingT1:
1662            lr = (pc + 2) | 1u; // return address
1663            imm32 = Bits32(opcode, 7, 0);
1664            mode = eModeThumb;
1665            break;
1666        case eEncodingA1:
1667            lr = pc + 4; // return address
1668            imm32 = Bits32(opcode, 23, 0);
1669            mode = eModeARM;
1670            break;
1671        default:
1672            return false;
1673        }
1674
1675        EmulateInstruction::Context context;
1676        context.type = EmulateInstruction::eContextSupervisorCall;
1677        context.SetModeAndImmediate (mode, imm32);
1678        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1679            return false;
1680    }
1681    return true;
1682}
1683
1684// If Then makes up to four following instructions (the IT block) conditional.
1685bool
1686EmulateInstructionARM::EmulateIT (ARMEncoding encoding)
1687{
1688#if 0
1689    // ARM pseudo code...
1690    EncodingSpecificOperations();
1691    ITSTATE.IT<7:0> = firstcond:mask;
1692#endif
1693
1694    bool success = false;
1695    const uint32_t opcode = OpcodeAsUnsigned (&success);
1696    if (!success)
1697        return false;
1698
1699    m_it_session.InitIT(Bits32(opcode, 7, 0));
1700    return true;
1701}
1702
1703// Branch causes a branch to a target address.
1704bool
1705EmulateInstructionARM::EmulateB (ARMEncoding encoding)
1706{
1707#if 0
1708    // ARM pseudo code...
1709    if (ConditionPassed())
1710    {
1711        EncodingSpecificOperations();
1712        BranchWritePC(PC + imm32);
1713    }
1714#endif
1715
1716    bool success = false;
1717    const uint32_t opcode = OpcodeAsUnsigned (&success);
1718    if (!success)
1719        return false;
1720
1721    if (ConditionPassed())
1722    {
1723        EmulateInstruction::Context context;
1724        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1725        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1726        if (!success)
1727            return false;
1728        addr_t target; // target address
1729        int32_t imm32; // PC-relative offset
1730        switch (encoding) {
1731        case eEncodingT1:
1732            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
1733            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
1734            target = pc + 4 + imm32;
1735            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1736            break;
1737        case eEncodingT2:
1738            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
1739            target = pc + 4 + imm32;
1740            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1741            break;
1742        case eEncodingT3:
1743            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
1744            {
1745            uint32_t S = Bit32(opcode, 26);
1746            uint32_t imm6 = Bits32(opcode, 21, 16);
1747            uint32_t J1 = Bit32(opcode, 13);
1748            uint32_t J2 = Bit32(opcode, 11);
1749            uint32_t imm11 = Bits32(opcode, 10, 0);
1750            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
1751            imm32 = llvm::SignExtend32<21>(imm21);
1752            target = pc + 4 + imm32;
1753            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1754            break;
1755            }
1756        case eEncodingT4:
1757            {
1758            uint32_t S = Bit32(opcode, 26);
1759            uint32_t imm10 = Bits32(opcode, 25, 16);
1760            uint32_t J1 = Bit32(opcode, 13);
1761            uint32_t J2 = Bit32(opcode, 11);
1762            uint32_t imm11 = Bits32(opcode, 10, 0);
1763            uint32_t I1 = !(J1 ^ S);
1764            uint32_t I2 = !(J2 ^ S);
1765            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1766            imm32 = llvm::SignExtend32<25>(imm25);
1767            target = pc + 4 + imm32;
1768            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1769            break;
1770            }
1771        case eEncodingA1:
1772            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1773            target = pc + 8 + imm32;
1774            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1775            break;
1776        default:
1777            return false;
1778        }
1779        if (!BranchWritePC(context, target))
1780            return false;
1781    }
1782    return true;
1783}
1784
1785// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
1786// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
1787// CBNZ, CBZ
1788bool
1789EmulateInstructionARM::EmulateCB (ARMEncoding encoding)
1790{
1791#if 0
1792    // ARM pseudo code...
1793    EncodingSpecificOperations();
1794    if nonzero ^ IsZero(R[n]) then
1795        BranchWritePC(PC + imm32);
1796#endif
1797
1798    bool success = false;
1799    const uint32_t opcode = OpcodeAsUnsigned (&success);
1800    if (!success)
1801        return false;
1802
1803    // Read the register value from the operand register Rn.
1804    uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success);
1805    if (!success)
1806        return false;
1807
1808    EmulateInstruction::Context context;
1809    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1810    const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1811    if (!success)
1812        return false;
1813
1814    addr_t target;  // target address
1815    uint32_t imm32; // PC-relative offset to branch forward
1816    bool nonzero;
1817    switch (encoding) {
1818    case eEncodingT1:
1819        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
1820        nonzero = BitIsSet(opcode, 11);
1821        target = pc + 4 + imm32;
1822        context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1823        break;
1824    default:
1825        return false;
1826    }
1827    if (nonzero ^ (reg_val == 0))
1828        if (!BranchWritePC(context, target))
1829            return false;
1830
1831    return true;
1832}
1833
1834// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
1835// A base register provides a pointer to the table, and a second register supplies an index into the table.
1836// The branch length is twice the value of the byte returned from the table.
1837//
1838// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
1839// A base register provides a pointer to the table, and a second register supplies an index into the table.
1840// The branch length is twice the value of the halfword returned from the table.
1841// TBB, TBH
1842bool
1843EmulateInstructionARM::EmulateTB (ARMEncoding encoding)
1844{
1845#if 0
1846    // ARM pseudo code...
1847    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
1848    if is_tbh then
1849        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
1850    else
1851        halfwords = UInt(MemU[R[n]+R[m], 1]);
1852    BranchWritePC(PC + 2*halfwords);
1853#endif
1854
1855    bool success = false;
1856    const uint32_t opcode = OpcodeAsUnsigned (&success);
1857    if (!success)
1858        return false;
1859
1860    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
1861    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
1862    bool is_tbh;     // true if table branch halfword
1863    switch (encoding) {
1864    case eEncodingT1:
1865        Rn = Bits32(opcode, 19, 16);
1866        Rm = Bits32(opcode, 3, 0);
1867        is_tbh = BitIsSet(opcode, 4);
1868        if (Rn == 13 || BadReg(Rm))
1869            return false;
1870        if (InITBlock() && !LastInITBlock())
1871            return false;
1872        break;
1873    default:
1874        return false;
1875    }
1876
1877    // Read the address of the table from the operand register Rn.
1878    // The PC can be used, in which case the table immediately follows this instruction.
1879    uint32_t base =
1880        Rn == 15 ? (ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success) + 4)
1881                 : ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
1882    if (!success)
1883        return false;
1884
1885    // the table index
1886    uint32_t index = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1887    if (!success)
1888        return false;
1889
1890    // the offsetted table address
1891    addr_t addr = base + (is_tbh ? index*2 : index);
1892
1893    // PC-relative offset to branch forward
1894    EmulateInstruction::Context context;
1895    context.type = EmulateInstruction::eContextTableBranchReadMemory;
1896    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
1897    if (!success)
1898        return false;
1899
1900    const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1901    if (!success)
1902        return false;
1903
1904    // target address
1905    addr_t target = pc + 4 + offset;
1906    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1907    context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
1908
1909    if (!BranchWritePC(context, target))
1910        return false;
1911
1912    return true;
1913}
1914
1915// This instruction adds a register value and an optionally-shifted register value, and writes the result
1916// to the destination register. It can optionally update the condition flags based on the result.
1917bool
1918EmulateInstructionARM::EmulateADDReg (ARMEncoding encoding)
1919{
1920#if 0
1921    // ARM pseudo code...
1922    if ConditionPassed() then
1923        EncodingSpecificOperations();
1924        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1925        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
1926        if d == 15 then
1927            ALUWritePC(result); // setflags is always FALSE here
1928        else
1929            R[d] = result;
1930            if setflags then
1931                APSR.N = result<31>;
1932                APSR.Z = IsZeroBit(result);
1933                APSR.C = carry;
1934                APSR.V = overflow;
1935#endif
1936
1937    bool success = false;
1938    const uint32_t opcode = OpcodeAsUnsigned (&success);
1939    if (!success)
1940        return false;
1941
1942    if (ConditionPassed())
1943    {
1944        uint32_t Rd, Rn, Rm;
1945        ARM_ShifterType shift_t;
1946        uint32_t shift_n; // the shift applied to the value read from Rm
1947        bool setflags;
1948        switch (encoding)
1949        {
1950        case eEncodingT1:
1951            Rd = Bits32(opcode, 2, 0);
1952            Rn = Bits32(opcode, 5, 3);
1953            Rm = Bits32(opcode, 8, 6);
1954            setflags = !InITBlock();
1955            shift_t = SRType_LSL;
1956            shift_n = 0;
1957        case eEncodingT2:
1958            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1959            Rm = Bits32(opcode, 6, 3);
1960            setflags = false;
1961            shift_t = SRType_LSL;
1962            shift_n = 0;
1963            if (Rn == 15 && Rm == 15)
1964                return false;
1965            if (Rd == 15 && InITBlock() && !LastInITBlock())
1966                return false;
1967            break;
1968        default:
1969            return false;
1970        }
1971
1972        int32_t result, val1, val2;
1973        // Read the first operand.
1974        if (Rn == 15)
1975        {
1976            val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1977            if (encoding == eEncodingT1 || encoding == eEncodingT2)
1978                val1 += 4;
1979            else
1980                val1 += 8;
1981        }
1982        else
1983            val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
1984        if (!success)
1985            return false;
1986
1987        // Read the second operand.
1988        if (Rm == 15)
1989        {
1990            val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1991            if (encoding == eEncodingT1 || encoding == eEncodingT2)
1992                val1 += 4;
1993            else
1994                val1 += 8;
1995        }
1996        else
1997            val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1998        if (!success)
1999            return false;
2000
2001        val2 = Shift(val2, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C));
2002        AddWithCarryResult res = AddWithCarry(val1, val2, 0);
2003        result = val1 + val2;
2004
2005        EmulateInstruction::Context context;
2006        context.type = EmulateInstruction::eContextImmediate;
2007        context.SetNoArgs ();
2008
2009        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2010            return false;
2011    }
2012    return true;
2013}
2014
2015// CMP (immediate)
2016bool
2017EmulateInstructionARM::EmulateCMPRnImm (ARMEncoding encoding)
2018{
2019#if 0
2020    // ARM pseudo code...
2021    if ConditionPassed() then
2022        EncodingSpecificOperations();
2023        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2024        APSR.N = result<31>;
2025        APSR.Z = IsZeroBit(result);
2026        APSR.C = carry;
2027        APSR.V = overflow;
2028#endif
2029
2030    bool success = false;
2031    const uint32_t opcode = OpcodeAsUnsigned (&success);
2032    if (!success)
2033        return false;
2034
2035    uint32_t Rn; // the first operand
2036    uint32_t imm32; // the immediate value to be compared with
2037    switch (encoding) {
2038    case eEncodingT1:
2039        Rn = Bits32(opcode, 10, 8);
2040        imm32 = Bits32(opcode, 7, 0);
2041        break;
2042    default:
2043        return false;
2044    }
2045    // Read the register value from the operand register Rn.
2046    uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2047    if (!success)
2048        return false;
2049
2050    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2051
2052    EmulateInstruction::Context context;
2053    context.type = EmulateInstruction::eContextImmediate;
2054    context.SetNoArgs ();
2055    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2056        return false;
2057
2058    return true;
2059}
2060
2061// CMP (register)
2062bool
2063EmulateInstructionARM::EmulateCMPRnRm (ARMEncoding encoding)
2064{
2065#if 0
2066    // ARM pseudo code...
2067    if ConditionPassed() then
2068        EncodingSpecificOperations();
2069        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2070        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2071        APSR.N = result<31>;
2072        APSR.Z = IsZeroBit(result);
2073        APSR.C = carry;
2074        APSR.V = overflow;
2075#endif
2076
2077    bool success = false;
2078    const uint32_t opcode = OpcodeAsUnsigned (&success);
2079    if (!success)
2080        return false;
2081
2082    uint32_t Rn; // the first operand
2083    uint32_t Rm; // the second operand
2084    switch (encoding) {
2085    case eEncodingT1:
2086        Rn = Bits32(opcode, 2, 0);
2087        Rm = Bits32(opcode, 5, 3);
2088        break;
2089    case eEncodingT2:
2090        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2091        Rm = Bits32(opcode, 6, 3);
2092        if (Rn < 8 && Rm < 8)
2093            return false;
2094        if (Rn == 15 || Rm == 15)
2095            return false;
2096        break;
2097    default:
2098        return false;
2099    }
2100    // Read the register value from register Rn.
2101    uint32_t reg_val1 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2102    if (!success)
2103        return false;
2104    // Read the register value from register Rm.
2105    // The register value is not being shifted since we don't handle ARM for now.
2106    uint32_t reg_val2 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
2107    if (!success)
2108        return false;
2109
2110    AddWithCarryResult res = AddWithCarry(reg_val1, ~reg_val2, 1);
2111
2112    EmulateInstruction::Context context;
2113    context.type = EmulateInstruction::eContextImmediate;
2114    context.SetNoArgs();
2115    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2116        return false;
2117
2118    return true;
2119}
2120
2121// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2122// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2123// optionally update the condition flags based on the result.
2124bool
2125EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding)
2126{
2127#if 0
2128    // ARM pseudo code...
2129    if ConditionPassed() then
2130        EncodingSpecificOperations();
2131        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2132        if d == 15 then         // Can only occur for ARM encoding
2133            ALUWritePC(result); // setflags is always FALSE here
2134        else
2135            R[d] = result;
2136            if setflags then
2137                APSR.N = result<31>;
2138                APSR.Z = IsZeroBit(result);
2139                APSR.C = carry;
2140                // APSR.V unchanged
2141#endif
2142
2143    return EmulateShiftImm(encoding, SRType_ASR);
2144}
2145
2146// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2147// shifting in copies of its sign bit, and writes the result to the destination register.
2148// The variable number of bits is read from the bottom byte of a register. It can optionally update
2149// the condition flags based on the result.
2150bool
2151EmulateInstructionARM::EmulateASRReg (ARMEncoding encoding)
2152{
2153#if 0
2154    // ARM pseudo code...
2155    if ConditionPassed() then
2156        EncodingSpecificOperations();
2157        shift_n = UInt(R[m]<7:0>);
2158        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2159        R[d] = result;
2160        if setflags then
2161            APSR.N = result<31>;
2162            APSR.Z = IsZeroBit(result);
2163            APSR.C = carry;
2164            // APSR.V unchanged
2165#endif
2166
2167    return EmulateShiftReg(encoding, SRType_ASR);
2168}
2169
2170// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2171// shifting in zeros, and writes the result to the destination register.  It can optionally
2172// update the condition flags based on the result.
2173bool
2174EmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding)
2175{
2176#if 0
2177    // ARM pseudo code...
2178    if ConditionPassed() then
2179        EncodingSpecificOperations();
2180        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2181        if d == 15 then         // Can only occur for ARM encoding
2182            ALUWritePC(result); // setflags is always FALSE here
2183        else
2184            R[d] = result;
2185            if setflags then
2186                APSR.N = result<31>;
2187                APSR.Z = IsZeroBit(result);
2188                APSR.C = carry;
2189                // APSR.V unchanged
2190#endif
2191
2192    return EmulateShiftImm(encoding, SRType_LSL);
2193}
2194
2195// Logical Shift Left (register) shifts a register value left by a variable number of bits,
2196// shifting in zeros, and writes the result to the destination register.  The variable number
2197// of bits is read from the bottom byte of a register. It can optionally update the condition
2198// flags based on the result.
2199bool
2200EmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding)
2201{
2202#if 0
2203    // ARM pseudo code...
2204    if ConditionPassed() then
2205        EncodingSpecificOperations();
2206        shift_n = UInt(R[m]<7:0>);
2207        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2208        R[d] = result;
2209        if setflags then
2210            APSR.N = result<31>;
2211            APSR.Z = IsZeroBit(result);
2212            APSR.C = carry;
2213            // APSR.V unchanged
2214#endif
2215
2216    return EmulateShiftReg(encoding, SRType_LSL);
2217}
2218
2219// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
2220// shifting in zeros, and writes the result to the destination register.  It can optionally
2221// update the condition flags based on the result.
2222bool
2223EmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding)
2224{
2225#if 0
2226    // ARM pseudo code...
2227    if ConditionPassed() then
2228        EncodingSpecificOperations();
2229        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2230        if d == 15 then         // Can only occur for ARM encoding
2231            ALUWritePC(result); // setflags is always FALSE here
2232        else
2233            R[d] = result;
2234            if setflags then
2235                APSR.N = result<31>;
2236                APSR.Z = IsZeroBit(result);
2237                APSR.C = carry;
2238                // APSR.V unchanged
2239#endif
2240
2241    return EmulateShiftImm(encoding, SRType_LSR);
2242}
2243
2244// Logical Shift Right (register) shifts a register value right by a variable number of bits,
2245// shifting in zeros, and writes the result to the destination register.  The variable number
2246// of bits is read from the bottom byte of a register. It can optionally update the condition
2247// flags based on the result.
2248bool
2249EmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding)
2250{
2251#if 0
2252    // ARM pseudo code...
2253    if ConditionPassed() then
2254        EncodingSpecificOperations();
2255        shift_n = UInt(R[m]<7:0>);
2256        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2257        R[d] = result;
2258        if setflags then
2259            APSR.N = result<31>;
2260            APSR.Z = IsZeroBit(result);
2261            APSR.C = carry;
2262            // APSR.V unchanged
2263#endif
2264
2265    return EmulateShiftReg(encoding, SRType_LSR);
2266}
2267
2268// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2269// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2270// It can optionally update the condition flags based on the result.
2271bool
2272EmulateInstructionARM::EmulateRORImm (ARMEncoding encoding)
2273{
2274#if 0
2275    // ARM pseudo code...
2276    if ConditionPassed() then
2277        EncodingSpecificOperations();
2278        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2279        if d == 15 then         // Can only occur for ARM encoding
2280            ALUWritePC(result); // setflags is always FALSE here
2281        else
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 unchanged
2288#endif
2289
2290    return EmulateShiftImm(encoding, SRType_ROR);
2291}
2292
2293// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
2294// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2295// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
2296// flags based on the result.
2297bool
2298EmulateInstructionARM::EmulateRORReg (ARMEncoding encoding)
2299{
2300#if 0
2301    // ARM pseudo code...
2302    if ConditionPassed() then
2303        EncodingSpecificOperations();
2304        shift_n = UInt(R[m]<7:0>);
2305        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2306        R[d] = result;
2307        if setflags then
2308            APSR.N = result<31>;
2309            APSR.Z = IsZeroBit(result);
2310            APSR.C = carry;
2311            // APSR.V unchanged
2312#endif
2313
2314    return EmulateShiftReg(encoding, SRType_ROR);
2315}
2316
2317// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
2318// with the carry flag shifted into bit [31].
2319//
2320// RRX can optionally update the condition flags based on the result.
2321// In that case, bit [0] is shifted into the carry flag.
2322bool
2323EmulateInstructionARM::EmulateRRX (ARMEncoding encoding)
2324{
2325#if 0
2326    // ARM pseudo code...
2327    if ConditionPassed() then
2328        EncodingSpecificOperations();
2329        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
2330        if d == 15 then         // Can only occur for ARM encoding
2331            ALUWritePC(result); // setflags is always FALSE here
2332        else
2333            R[d] = result;
2334            if setflags then
2335                APSR.N = result<31>;
2336                APSR.Z = IsZeroBit(result);
2337                APSR.C = carry;
2338                // APSR.V unchanged
2339#endif
2340
2341    return EmulateShiftImm(encoding, SRType_RRX);
2342}
2343
2344bool
2345EmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type)
2346{
2347    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
2348
2349    bool success = false;
2350    const uint32_t opcode = OpcodeAsUnsigned (&success);
2351    if (!success)
2352        return false;
2353
2354    if (ConditionPassed())
2355    {
2356        uint32_t Rd;    // the destination register
2357        uint32_t Rm;    // the first operand register
2358        uint32_t imm5;  // encoding for the shift amount
2359        uint32_t carry; // the carry bit after the shift operation
2360        bool setflags;
2361
2362        // Special case handling!
2363        // A8.6.139 ROR (immediate) -- Encoding T1
2364        if (shift_type == SRType_ROR && encoding == eEncodingT1)
2365        {
2366            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
2367            // have the same decoding of bit fields as the other Thumb2 shift operations.
2368            encoding = eEncodingT2;
2369        }
2370
2371        switch (encoding) {
2372        case eEncodingT1:
2373            // Due to the above special case handling!
2374            assert(shift_type != SRType_ROR);
2375
2376            Rd = Bits32(opcode, 2, 0);
2377            Rm = Bits32(opcode, 5, 3);
2378            setflags = !InITBlock();
2379            imm5 = Bits32(opcode, 10, 6);
2380            break;
2381        case eEncodingT2:
2382            // A8.6.141 RRX
2383            assert(shift_type != SRType_RRX);
2384
2385            Rd = Bits32(opcode, 11, 8);
2386            Rm = Bits32(opcode, 3, 0);
2387            setflags = BitIsSet(opcode, 20);
2388            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
2389            if (BadReg(Rd) || BadReg(Rm))
2390                return false;
2391            break;
2392        case eEncodingA1:
2393            Rd = Bits32(opcode, 15, 12);
2394            Rm = Bits32(opcode, 3, 0);
2395            setflags = BitIsSet(opcode, 20);
2396            imm5 = Bits32(opcode, 11, 7);
2397            break;
2398        default:
2399            return false;
2400        }
2401
2402        // A8.6.139 ROR (immediate)
2403        if (shift_type == SRType_ROR && imm5 == 0)
2404            shift_type = SRType_RRX;
2405
2406        // Get the first operand.
2407        uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
2408        if (!success)
2409            return false;
2410
2411        // Decode the shift amount if not RRX.
2412        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
2413
2414        uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
2415
2416        // The context specifies that an immediate is to be moved into Rd.
2417        EmulateInstruction::Context context;
2418        context.type = EmulateInstruction::eContextImmediate;
2419        context.SetNoArgs ();
2420
2421        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
2422            return false;
2423    }
2424    return true;
2425}
2426
2427bool
2428EmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type)
2429{
2430    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
2431
2432    bool success = false;
2433    const uint32_t opcode = OpcodeAsUnsigned (&success);
2434    if (!success)
2435        return false;
2436
2437    if (ConditionPassed())
2438    {
2439        uint32_t Rd;    // the destination register
2440        uint32_t Rn;    // the first operand register
2441        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
2442        uint32_t carry; // the carry bit after the shift operation
2443        bool setflags;
2444        switch (encoding) {
2445        case eEncodingT1:
2446            Rd = Bits32(opcode, 2, 0);
2447            Rn = Rd;
2448            Rm = Bits32(opcode, 5, 3);
2449            setflags = !InITBlock();
2450            break;
2451        case eEncodingT2:
2452            Rd = Bits32(opcode, 11, 8);
2453            Rn = Bits32(opcode, 19, 16);
2454            Rm = Bits32(opcode, 3, 0);
2455            setflags = BitIsSet(opcode, 20);
2456            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
2457                return false;
2458            break;
2459        case eEncodingA1:
2460            Rd = Bits32(opcode, 15, 12);
2461            Rn = Bits32(opcode, 3, 0);
2462            Rm = Bits32(opcode, 11, 8);
2463            setflags = BitIsSet(opcode, 20);
2464            if (Rd == 15 || Rn == 15 || Rm == 15)
2465                return false;
2466            break;
2467        default:
2468            return false;
2469        }
2470
2471        // Get the first operand.
2472        uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2473        if (!success)
2474            return false;
2475        // Get the Rm register content.
2476        uint32_t val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
2477        if (!success)
2478            return false;
2479
2480        // Get the shift amount.
2481        uint32_t amt = Bits32(val, 7, 0);
2482
2483        uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
2484
2485        // The context specifies that an immediate is to be moved into Rd.
2486        EmulateInstruction::Context context;
2487        context.type = EmulateInstruction::eContextImmediate;
2488        context.SetNoArgs ();
2489
2490        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
2491            return false;
2492    }
2493    return true;
2494}
2495
2496// LDM loads multiple registers from consecutive memory locations, using an
2497// address from a base register.  Optionally the address just above the highest of those locations
2498// can be written back to the base register.
2499bool
2500EmulateInstructionARM::EmulateLDM (ARMEncoding encoding)
2501{
2502#if 0
2503    // ARM pseudo code...
2504    if ConditionPassed()
2505        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
2506        address = R[n];
2507
2508        for i = 0 to 14
2509            if registers<i> == '1' then
2510                R[i] = MemA[address, 4]; address = address + 4;
2511        if registers<15> == '1' then
2512            LoadWritePC (MemA[address, 4]);
2513
2514        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
2515        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
2516
2517#endif
2518
2519    bool success = false;
2520    const uint32_t opcode = OpcodeAsUnsigned (&success);
2521    if (!success)
2522        return false;
2523
2524    if (ConditionPassed())
2525    {
2526        uint32_t n;
2527        uint32_t registers = 0;
2528        bool wback;
2529        const uint32_t addr_byte_size = GetAddressByteSize();
2530        switch (encoding)
2531        {
2532            case eEncodingT1:
2533                // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’);
2534                n = Bits32 (opcode, 10, 8);
2535                registers = Bits32 (opcode, 7, 0);
2536                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
2537                wback = BitIsClear (registers, n);
2538                // if BitCount(registers) < 1 then UNPREDICTABLE;
2539                if (BitCount(registers) < 1)
2540                    return false;
2541                break;
2542            case eEncodingT2:
2543                // if W == ’1’ && Rn == ’1101’ then SEE POP;
2544                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
2545                n = Bits32 (opcode, 19, 16);
2546                registers = Bits32 (opcode, 15, 0);
2547                registers = registers & 0xdfff; // Make sure bit 13 is zero.
2548                wback = BitIsSet (opcode, 21);
2549
2550                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
2551                if ((n == 15)
2552                    || (BitCount (registers) < 2)
2553                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
2554                    return false;
2555
2556                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
2557                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
2558                    return false;
2559
2560                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
2561                if (wback
2562                    && BitIsSet (registers, n))
2563                    return false;
2564                break;
2565
2566            case eEncodingA1:
2567                n = Bits32 (opcode, 19, 16);
2568                registers = Bits32 (opcode, 15, 0);
2569                wback = BitIsSet (opcode, 21);
2570                if ((n == 15)
2571                    || (BitCount (registers) < 1))
2572                    return false;
2573                break;
2574            default:
2575                return false;
2576        }
2577
2578        int32_t offset = 0;
2579        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2580        if (!success)
2581            return false;
2582
2583        EmulateInstruction::Context context;
2584        context.type = EmulateInstruction::eContextRegisterPlusOffset;
2585        Register dwarf_reg;
2586        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2587        context.SetRegisterPlusOffset (dwarf_reg, offset);
2588
2589        for (int i = 0; i < 14; ++i)
2590        {
2591            if (BitIsSet (registers, i))
2592            {
2593                context.type = EmulateInstruction::eContextRegisterPlusOffset;
2594                context.SetRegisterPlusOffset (dwarf_reg, offset);
2595                if (wback && (n == 13)) // Pop Instruction
2596                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2597
2598                // R[i] = MemA [address, 4]; address = address + 4;
2599                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
2600                if (!success)
2601                    return false;
2602
2603                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2604                    return false;
2605
2606                offset += addr_byte_size;
2607            }
2608        }
2609
2610        if (BitIsSet (registers, 15))
2611        {
2612            //LoadWritePC (MemA [address, 4]);
2613            context.type = EmulateInstruction::eContextRegisterPlusOffset;
2614            context.SetRegisterPlusOffset (dwarf_reg, offset);
2615            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
2616            if (!success)
2617                return false;
2618            // In ARMv5T and above, this is an interworking branch.
2619            if (!LoadWritePC(context, data))
2620                return false;
2621        }
2622
2623        if (wback && BitIsClear (registers, n))
2624        {
2625            // R[n] = R[n] + 4 * BitCount (registers)
2626            int32_t offset = addr_byte_size * BitCount (registers);
2627            context.type = EmulateInstruction::eContextAdjustBaseRegister;
2628            context.SetRegisterPlusOffset (dwarf_reg, offset);
2629
2630            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
2631                return false;
2632        }
2633        if (wback && BitIsSet (registers, n))
2634            // R[n] bits(32) UNKNOWN;
2635            return WriteBits32Unknown (n);
2636    }
2637    return true;
2638}
2639
2640// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers.
2641// The consecutive memorty locations end at this address and the address just below the lowest of those locations
2642// can optionally be written back tot he base registers.
2643bool
2644EmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding)
2645{
2646#if 0
2647    // ARM pseudo code...
2648    if ConditionPassed() then
2649        EncodingSpecificOperations();
2650        address = R[n] - 4*BitCount(registers) + 4;
2651
2652        for i = 0 to 14
2653            if registers<i> == ’1then
2654                  R[i] = MemA[address,4]; address = address + 4;
2655
2656        if registers<15> == ’1then
2657            LoadWritePC(MemA[address,4]);
2658
2659        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2660        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
2661#endif
2662
2663    bool success = false;
2664    const uint32_t opcode = OpcodeAsUnsigned (&success);
2665    if (!success)
2666        return false;
2667
2668    if (ConditionPassed())
2669    {
2670        uint32_t n;
2671        uint32_t registers = 0;
2672        bool wback;
2673        const uint32_t addr_byte_size = GetAddressByteSize();
2674
2675        // EncodingSpecificOperations();
2676        switch (encoding)
2677        {
2678            case eEncodingA1:
2679                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
2680                n = Bits32 (opcode, 19, 16);
2681                registers = Bits32 (opcode, 15, 0);
2682                wback = BitIsSet (opcode, 21);
2683
2684                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
2685                if ((n == 15) || (BitCount (registers) < 1))
2686                    return false;
2687
2688                break;
2689
2690            default:
2691                return false;
2692        }
2693        // address = R[n] - 4*BitCount(registers) + 4;
2694
2695        int32_t offset = 0;
2696        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2697
2698        if (!success)
2699            return false;
2700
2701        address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size;
2702
2703        EmulateInstruction::Context context;
2704        context.type = EmulateInstruction::eContextRegisterPlusOffset;
2705        Register dwarf_reg;
2706        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2707        context.SetRegisterPlusOffset (dwarf_reg, offset);
2708
2709        // for i = 0 to 14
2710        for (int i = 0; i < 14; ++i)
2711        {
2712            // if registers<i> == ’1’ then
2713            if (BitIsSet (registers, i))
2714            {
2715                  // R[i] = MemA[address,4]; address = address + 4;
2716                  context.SetRegisterPlusOffset (dwarf_reg, offset);
2717                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2718                  if (!success)
2719                      return false;
2720                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2721                      return false;
2722                  offset += addr_byte_size;
2723            }
2724        }
2725
2726        // if registers<15> == ’1’ then
2727        //     LoadWritePC(MemA[address,4]);
2728        if (BitIsSet (registers, 15))
2729        {
2730            context.SetRegisterPlusOffset (dwarf_reg, offset);
2731            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2732            if (!success)
2733                return false;
2734            // In ARMv5T and above, this is an interworking branch.
2735            if (!LoadWritePC(context, data))
2736                return false;
2737        }
2738
2739        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2740        if (wback && BitIsClear (registers, n))
2741        {
2742            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2743            if (!success)
2744                return false;
2745
2746            offset = (addr_byte_size * BitCount (registers)) * -1;
2747            context.type = EmulateInstruction::eContextAdjustBaseRegister;
2748            context.SetImmediateSigned (offset);
2749            addr = addr + offset;
2750            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
2751                return false;
2752        }
2753
2754        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN;
2755        if (wback && BitIsSet (registers, n))
2756            return WriteBits32Unknown (n);
2757    }
2758    return true;
2759}
2760
2761// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
2762// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
2763// be optionally written back to the base register.
2764bool
2765EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding)
2766{
2767#if 0
2768    // ARM pseudo code...
2769    if ConditionPassed() then
2770        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2771        address = R[n] - 4*BitCount(registers);
2772
2773        for i = 0 to 14
2774            if registers<i> == ’1then
2775                  R[i] = MemA[address,4]; address = address + 4;
2776        if registers<15> == ’1then
2777                  LoadWritePC(MemA[address,4]);
2778
2779        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2780        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
2781#endif
2782
2783    bool success = false;
2784    const uint32_t opcode = OpcodeAsUnsigned (&success);
2785    if (!success)
2786        return false;
2787
2788    if (ConditionPassed())
2789    {
2790        uint32_t n;
2791        uint32_t registers = 0;
2792        bool wback;
2793        const uint32_t addr_byte_size = GetAddressByteSize();
2794        switch (encoding)
2795        {
2796            case eEncodingT1:
2797                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
2798                n = Bits32 (opcode, 19, 16);
2799                registers = Bits32 (opcode, 15, 0);
2800                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
2801                wback = BitIsSet (opcode, 21);
2802
2803                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
2804                if ((n == 15)
2805                    || (BitCount (registers) < 2)
2806                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
2807                    return false;
2808
2809                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
2810                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
2811                    return false;
2812
2813                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
2814                if (wback && BitIsSet (registers, n))
2815                    return false;
2816
2817                break;
2818
2819            case eEncodingA1:
2820                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
2821                n = Bits32 (opcode, 19, 16);
2822                registers = Bits32 (opcode, 15, 0);
2823                wback = BitIsSet (opcode, 21);
2824
2825                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
2826                if ((n == 15) || (BitCount (registers) < 1))
2827                    return false;
2828
2829                break;
2830
2831            default:
2832                return false;
2833        }
2834
2835        // address = R[n] - 4*BitCount(registers);
2836
2837        int32_t offset = 0;
2838        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2839
2840        if (!success)
2841            return false;
2842
2843        address = address - (addr_byte_size * BitCount (registers));
2844        EmulateInstruction::Context context;
2845        context.type = EmulateInstruction::eContextRegisterPlusOffset;
2846        Register dwarf_reg;
2847        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2848        context.SetRegisterPlusOffset (dwarf_reg, offset);
2849
2850        for (int i = 0; i < 14; ++i)
2851        {
2852            if (BitIsSet (registers, i))
2853            {
2854                // R[i] = MemA[address,4]; address = address + 4;
2855                context.SetRegisterPlusOffset (dwarf_reg, offset);
2856                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2857                if (!success)
2858                    return false;
2859
2860                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2861                    return false;
2862
2863                offset += addr_byte_size;
2864            }
2865        }
2866
2867        // if registers<15> == ’1’ then
2868        //     LoadWritePC(MemA[address,4]);
2869        if (BitIsSet (registers, 15))
2870        {
2871            context.SetRegisterPlusOffset (dwarf_reg, offset);
2872            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2873            if (!success)
2874                return false;
2875            // In ARMv5T and above, this is an interworking branch.
2876            if (!LoadWritePC(context, data))
2877                return false;
2878        }
2879
2880        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2881        if (wback && BitIsClear (registers, n))
2882        {
2883            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2884            if (!success)
2885                return false;
2886
2887            offset = (addr_byte_size * BitCount (registers)) * -1;
2888            context.type = EmulateInstruction::eContextAdjustBaseRegister;
2889            context.SetImmediateSigned (offset);
2890            addr = addr + offset;
2891            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
2892                return false;
2893        }
2894
2895        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
2896        if (wback && BitIsSet (registers, n))
2897            return WriteBits32Unknown (n);
2898    }
2899    return true;
2900}
2901
2902// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
2903// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
2904// optinoally be written back to the base register.
2905bool
2906EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding)
2907{
2908#if 0
2909    if ConditionPassed() then
2910        EncodingSpecificOperations();
2911        address = R[n] + 4;
2912
2913        for i = 0 to 14
2914            if registers<i> == ’1then
2915                  R[i] = MemA[address,4]; address = address + 4;
2916        if registers<15> == ’1then
2917            LoadWritePC(MemA[address,4]);
2918
2919        if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
2920        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
2921#endif
2922
2923    bool success = false;
2924    const uint32_t opcode = OpcodeAsUnsigned (&success);
2925    if (!success)
2926        return false;
2927
2928    if (ConditionPassed())
2929    {
2930        uint32_t n;
2931        uint32_t registers = 0;
2932        bool wback;
2933        const uint32_t addr_byte_size = GetAddressByteSize();
2934        switch (encoding)
2935        {
2936            case eEncodingA1:
2937                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
2938                n = Bits32 (opcode, 19, 16);
2939                registers = Bits32 (opcode, 15, 0);
2940                wback = BitIsSet (opcode, 21);
2941
2942                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
2943                if ((n == 15) || (BitCount (registers) < 1))
2944                    return false;
2945
2946                break;
2947            default:
2948                return false;
2949        }
2950        // address = R[n] + 4;
2951
2952        int32_t offset = 0;
2953        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2954
2955        if (!success)
2956            return false;
2957
2958        address = address + addr_byte_size;
2959
2960        EmulateInstruction::Context context;
2961        context.type = EmulateInstruction::eContextRegisterPlusOffset;
2962        Register dwarf_reg;
2963        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2964        context.SetRegisterPlusOffset (dwarf_reg, offset);
2965
2966        for (int i = 0; i < 14; ++i)
2967        {
2968            if (BitIsSet (registers, i))
2969            {
2970                // R[i] = MemA[address,4]; address = address + 4;
2971
2972                context.SetRegisterPlusOffset (dwarf_reg, offset);
2973                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2974                if (!success)
2975                    return false;
2976
2977                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2978                    return false;
2979
2980                offset += addr_byte_size;
2981            }
2982        }
2983
2984        // if registers<15> == ’1’ then
2985        //     LoadWritePC(MemA[address,4]);
2986        if (BitIsSet (registers, 15))
2987        {
2988            context.SetRegisterPlusOffset (dwarf_reg, offset);
2989            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2990            if (!success)
2991                return false;
2992            // In ARMv5T and above, this is an interworking branch.
2993            if (!LoadWritePC(context, data))
2994                return false;
2995        }
2996
2997        // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
2998        if (wback && BitIsClear (registers, n))
2999        {
3000            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3001            if (!success)
3002                return false;
3003
3004            offset = addr_byte_size * BitCount (registers);
3005            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3006            context.SetImmediateSigned (offset);
3007            addr = addr + offset;
3008            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3009                return false;
3010        }
3011
3012        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3013        if (wback && BitIsSet (registers, n))
3014            return WriteBits32Unknown (n);
3015    }
3016    return true;
3017}
3018
3019// Load Register (immediate) calculates an address from a base register value and
3020// an immediate offset, loads a word from memory, and writes to a register.
3021// LDR (immediate, Thumb)
3022bool
3023EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
3024{
3025#if 0
3026    // ARM pseudo code...
3027    if (ConditionPassed())
3028    {
3029        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3030        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3031        address = if index then offset_addr else R[n];
3032        data = MemU[address,4];
3033        if wback then R[n] = offset_addr;
3034        if t == 15 then
3035            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3036        elsif UnalignedSupport() || address<1:0> = '00' then
3037            R[t] = data;
3038        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3039    }
3040#endif
3041
3042    bool success = false;
3043    const uint32_t opcode = OpcodeAsUnsigned (&success);
3044    if (!success)
3045        return false;
3046
3047    if (ConditionPassed())
3048    {
3049        uint32_t Rt; // the destination register
3050        uint32_t Rn; // the base register
3051        uint32_t imm32; // the immediate offset used to form the address
3052        addr_t offset_addr; // the offset address
3053        addr_t address; // the calculated address
3054        uint32_t data; // the literal data value from memory load
3055        bool add, index, wback;
3056        switch (encoding) {
3057        case eEncodingT1:
3058            Rt = Bits32(opcode, 5, 3);
3059            Rn = Bits32(opcode, 2, 0);
3060            imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3061            // index = TRUE; add = TRUE; wback = FALSE
3062            add = true;
3063            index = true;
3064            wback = false;
3065            break;
3066        default:
3067            return false;
3068        }
3069        uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
3070        if (!success)
3071            return false;
3072        if (add)
3073            offset_addr = base + imm32;
3074        else
3075            offset_addr = base - imm32;
3076
3077        address = (index ? offset_addr : base);
3078
3079        if (wback)
3080        {
3081            EmulateInstruction::Context ctx;
3082            ctx.type = EmulateInstruction::eContextRegisterPlusOffset;
3083            Register dwarf_reg;
3084            dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
3085            ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base));
3086
3087            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3088                return false;
3089        }
3090
3091        // Prepare to write to the Rt register.
3092        EmulateInstruction::Context context;
3093        context.type = EmulateInstruction::eContextImmediate;
3094        context.SetNoArgs ();
3095
3096        // Read memory from the address.
3097        data = MemURead(context, address, 4, 0, &success);
3098        if (!success)
3099            return false;
3100
3101        if (Rt == 15)
3102        {
3103            if (Bits32(address, 1, 0) == 0)
3104            {
3105                if (!LoadWritePC(context, data))
3106                    return false;
3107            }
3108            else
3109                return false;
3110        }
3111        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3112        {
3113            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3114                return false;
3115        }
3116        else
3117            return false;
3118    }
3119    return true;
3120}
3121
3122// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3123// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3124// of those locations can optionally be written back to the base register.
3125bool
3126EmulateInstructionARM::EmulateSTM (ARMEncoding encoding)
3127{
3128#if 0
3129    if ConditionPassed() then
3130        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3131        address = R[n];
3132
3133        for i = 0 to 14
3134            if registers<i> == ’1then
3135                if i == n && wback && i != LowestSetBit(registers) then
3136                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3137                else
3138                    MemA[address,4] = R[i];
3139                address = address + 4;
3140
3141        if registers<15> == ’1then // Only possible for encoding A1
3142            MemA[address,4] = PCStoreValue();
3143        if wback then R[n] = R[n] + 4*BitCount(registers);
3144#endif
3145
3146    bool success = false;
3147    const uint32_t opcode = OpcodeAsUnsigned (&success);
3148    if (!success)
3149        return false;
3150
3151    if (ConditionPassed ())
3152    {
3153        uint32_t n;
3154        uint32_t registers = 0;
3155        bool wback;
3156        const uint32_t addr_byte_size = GetAddressByteSize();
3157
3158        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3159        switch (encoding)
3160        {
3161            case eEncodingT1:
3162                // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE;
3163                n = Bits32 (opcode, 10, 8);
3164                registers = Bits32 (opcode, 7, 0);
3165                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3166                wback = true;
3167
3168                // if BitCount(registers) < 1 then UNPREDICTABLE;
3169                if (BitCount (registers) < 1)
3170                    return false;
3171
3172                break;
3173
3174            case eEncodingT2:
3175                // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’);
3176                n = Bits32 (opcode, 19, 16);
3177                registers = Bits32 (opcode, 15, 0);
3178                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3179                wback = BitIsSet (opcode, 21);
3180
3181                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3182                if ((n == 15) || (BitCount (registers) < 2))
3183                    return false;
3184
3185                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
3186                if (wback && BitIsSet (registers, n))
3187                    return false;
3188
3189                break;
3190
3191            case eEncodingA1:
3192                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3193                n = Bits32 (opcode, 19, 16);
3194                registers = Bits32 (opcode, 15, 0);
3195                wback = BitIsSet (opcode, 21);
3196
3197                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3198                if ((n == 15) || (BitCount (registers) < 1))
3199                    return false;
3200
3201                break;
3202
3203            default:
3204                return false;
3205        }
3206
3207        // address = R[n];
3208        int32_t offset = 0;
3209        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3210        if (!success)
3211            return false;
3212
3213        EmulateInstruction::Context context;
3214        context.type = EmulateInstruction::eContextRegisterStore;
3215        Register base_reg;
3216        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3217
3218        // for i = 0 to 14
3219        for (int i = 0; i < 14; ++i)
3220        {
3221            int lowest_set_bit = 14;
3222            // if registers<i> == ’1’ then
3223            if (BitIsSet (registers, i))
3224            {
3225                  if (i < lowest_set_bit)
3226                      lowest_set_bit = i;
3227                  // if i == n && wback && i != LowestSetBit(registers) then
3228                  if ((i == n) && wback && (i != lowest_set_bit))
3229                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3230                      WriteBits32UnknownToMemory (address + offset);
3231                  else
3232                  {
3233                     // MemA[address,4] = R[i];
3234                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3235                      if (!success)
3236                          return false;
3237
3238                      Register data_reg;
3239                      data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3240                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3241                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
3242                          return false;
3243                  }
3244
3245                  // address = address + 4;
3246                  offset += addr_byte_size;
3247            }
3248        }
3249
3250        // if registers<15> == ’1’ then // Only possible for encoding A1
3251        //     MemA[address,4] = PCStoreValue();
3252        if (BitIsSet (registers, 15))
3253        {
3254            Register pc_reg;
3255            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3256            context.SetRegisterPlusOffset (pc_reg, 8);
3257            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3258            if (!success)
3259                return false;
3260
3261            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3262                return false;
3263        }
3264
3265        // if wback then R[n] = R[n] + 4*BitCount(registers);
3266        if (wback)
3267        {
3268            offset = addr_byte_size * BitCount (registers);
3269            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3270            context.SetImmediateSigned (offset);
3271            addr_t data = address + offset;
3272            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3273                return false;
3274        }
3275    }
3276    return true;
3277}
3278
3279// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
3280// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
3281// of those locations can optionally be written back to the base register.
3282bool
3283EmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding)
3284{
3285#if 0
3286    if ConditionPassed() then
3287        EncodingSpecificOperations();
3288        address = R[n] - 4*BitCount(registers) + 4;
3289
3290        for i = 0 to 14
3291            if registers<i> == ’1then
3292                if i == n && wback && i != LowestSetBit(registers) then
3293                    MemA[address,4] = bits(32) UNKNOWN;
3294                else
3295                    MemA[address,4] = R[i];
3296                address = address + 4;
3297
3298        if registers<15> == ’1then
3299            MemA[address,4] = PCStoreValue();
3300
3301        if wback then R[n] = R[n] - 4*BitCount(registers);
3302#endif
3303
3304    bool success = false;
3305    const uint32_t opcode = OpcodeAsUnsigned (&success);
3306    if (!success)
3307        return false;
3308
3309    if (ConditionPassed ())
3310    {
3311        uint32_t n;
3312        uint32_t registers = 0;
3313        bool wback;
3314        const uint32_t addr_byte_size = GetAddressByteSize();
3315
3316        // EncodingSpecificOperations();
3317        switch (encoding)
3318        {
3319            case eEncodingA1:
3320                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3321                n = Bits32 (opcode, 19, 16);
3322                registers = Bits32 (opcode, 15, 0);
3323                wback = BitIsSet (opcode, 21);
3324
3325                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3326                if ((n == 15) || (BitCount (registers) < 1))
3327                    return false;
3328                break;
3329            default:
3330                return false;
3331        }
3332
3333        // address = R[n] - 4*BitCount(registers) + 4;
3334        int32_t offset = 0;
3335        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3336        if (!success)
3337            return false;
3338
3339        address = address - (addr_byte_size * BitCount (registers)) + 4;
3340
3341        EmulateInstruction::Context context;
3342        context.type = EmulateInstruction::eContextRegisterStore;
3343        Register base_reg;
3344        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3345
3346        // for i = 0 to 14
3347        for (int i = 0; i < 14; ++i)
3348        {
3349            int lowest_bit_set = 14;
3350            // if registers<i> == ’1’ then
3351            if (BitIsSet (registers, i))
3352            {
3353                if (i < lowest_bit_set)
3354                    lowest_bit_set = i;
3355                //if i == n && wback && i != LowestSetBit(registers) then
3356                if ((i == n) && wback && (i != lowest_bit_set))
3357                    // MemA[address,4] = bits(32) UNKNOWN;
3358                    WriteBits32UnknownToMemory (address + offset);
3359                else
3360                {
3361                    // MemA[address,4] = R[i];
3362                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3363                    if (!success)
3364                        return false;
3365
3366                    Register data_reg;
3367                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3368                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3369                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3370                        return false;
3371                }
3372
3373                // address = address + 4;
3374                offset += addr_byte_size;
3375            }
3376        }
3377
3378        // if registers<15> == ’1’ then
3379        //    MemA[address,4] = PCStoreValue();
3380        if (BitIsSet (registers, 15))
3381        {
3382            Register pc_reg;
3383            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3384            context.SetRegisterPlusOffset (pc_reg, 8);
3385            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3386            if (!success)
3387                return false;
3388
3389            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3390                return false;
3391        }
3392
3393        // if wback then R[n] = R[n] - 4*BitCount(registers);
3394        if (wback)
3395        {
3396            offset = (addr_byte_size * BitCount (registers)) * -1;
3397            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3398            context.SetImmediateSigned (offset);
3399            addr_t data = address + offset;
3400            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3401                return false;
3402        }
3403    }
3404    return true;
3405}
3406
3407// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
3408// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
3409// those locations can optionally be written back to the base register.
3410bool
3411EmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding)
3412{
3413#if 0
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> == ’1then
3420                if i == n && wback && i != LowestSetBit(registers) then
3421                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
3422                else
3423                    MemA[address,4] = R[i];
3424                address = address + 4;
3425
3426        if registers<15> == ’1then // Only possible for encoding A1
3427            MemA[address,4] = PCStoreValue();
3428
3429        if wback then R[n] = R[n] - 4*BitCount(registers);
3430#endif
3431
3432
3433    bool success = false;
3434    const uint32_t opcode = OpcodeAsUnsigned (&success);
3435    if (!success)
3436        return false;
3437
3438    if (ConditionPassed ())
3439    {
3440        uint32_t n;
3441        uint32_t registers = 0;
3442        bool wback;
3443        const uint32_t addr_byte_size = GetAddressByteSize();
3444
3445        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3446        switch (encoding)
3447        {
3448            case eEncodingT1:
3449                // if W == ’1’ && Rn == ’1101’ then SEE PUSH;
3450                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
3451                {
3452                    // See PUSH
3453                }
3454                // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’);
3455                n = Bits32 (opcode, 19, 16);
3456                registers = Bits32 (opcode, 15, 0);
3457                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
3458                wback = BitIsSet (opcode, 21);
3459                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3460                if ((n == 15) || BitCount (registers) < 2)
3461                    return false;
3462                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
3463                if (wback && BitIsSet (registers, n))
3464                    return false;
3465                break;
3466
3467            case eEncodingA1:
3468                // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH;
3469                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
3470                {
3471                    // See Push
3472                }
3473                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3474                n = Bits32 (opcode, 19, 16);
3475                registers = Bits32 (opcode, 15, 0);
3476                wback = BitIsSet (opcode, 21);
3477                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3478                if ((n == 15) || BitCount (registers) < 1)
3479                    return false;
3480                break;
3481
3482            default:
3483                return false;
3484        }
3485
3486        // address = R[n] - 4*BitCount(registers);
3487
3488        int32_t offset = 0;
3489        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3490        if (!success)
3491        return false;
3492
3493        address = address - (addr_byte_size * BitCount (registers));
3494
3495        EmulateInstruction::Context context;
3496        context.type = EmulateInstruction::eContextRegisterStore;
3497        Register base_reg;
3498        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3499
3500        // for i = 0 to 14
3501        for (int i = 0; i < 14; ++i)
3502        {
3503            uint32_t lowest_set_bit = 14;
3504            // if registers<i> == ’1’ then
3505            if (BitIsSet (registers, i))
3506            {
3507                if (i < lowest_set_bit)
3508                    lowest_set_bit = i;
3509                // if i == n && wback && i != LowestSetBit(registers) then
3510                if ((i == n) && wback && (i != lowest_set_bit))
3511                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
3512                    WriteBits32UnknownToMemory (address + offset);
3513                else
3514                {
3515                    // MemA[address,4] = R[i];
3516                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3517                    if (!success)
3518                        return false;
3519
3520                    Register data_reg;
3521                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3522                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3523                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3524                        return false;
3525                }
3526
3527                // address = address + 4;
3528                offset += addr_byte_size;
3529            }
3530        }
3531
3532        // if registers<15> == ’1’ then // Only possible for encoding A1
3533        //     MemA[address,4] = PCStoreValue();
3534        if (BitIsSet (registers, 15))
3535        {
3536            Register pc_reg;
3537            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3538            context.SetRegisterPlusOffset (pc_reg, 8);
3539            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3540            if (!success)
3541                return false;
3542
3543            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3544                return false;
3545        }
3546
3547        // if wback then R[n] = R[n] - 4*BitCount(registers);
3548        if (wback)
3549        {
3550            offset = (addr_byte_size * BitCount (registers)) * -1;
3551            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3552            context.SetImmediateSigned (offset);
3553            addr_t data = address + offset;
3554            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3555                return false;
3556        }
3557    }
3558    return true;
3559}
3560
3561// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
3562// from a base register.  The consecutive memory locations start just above this address, and the address of the last
3563// of those locations can optionally be written back to the base register.
3564bool
3565EmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding)
3566{
3567#if 0
3568    if ConditionPassed() then
3569        EncodingSpecificOperations();
3570        address = R[n] + 4;
3571
3572        for i = 0 to 14
3573            if registers<i> == ’1then
3574                if i == n && wback && i != LowestSetBit(registers) then
3575                    MemA[address,4] = bits(32) UNKNOWN;
3576                else
3577                    MemA[address,4] = R[i];
3578                address = address + 4;
3579
3580        if registers<15> == ’1then
3581            MemA[address,4] = PCStoreValue();
3582
3583        if wback then R[n] = R[n] + 4*BitCount(registers);
3584#endif
3585
3586    bool success = false;
3587    const uint32_t opcode = OpcodeAsUnsigned (&success);
3588    if (!success)
3589        return false;
3590
3591    if (ConditionPassed())
3592    {
3593        uint32_t n;
3594        uint32_t registers = 0;
3595        bool wback;
3596        const uint32_t addr_byte_size = GetAddressByteSize();
3597
3598        // EncodingSpecificOperations();
3599        switch (encoding)
3600        {
3601            case eEncodingA1:
3602                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3603                n = Bits32 (opcode, 19, 16);
3604                registers = Bits32 (opcode, 15, 0);
3605                wback = BitIsSet (opcode, 21);
3606
3607                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3608                if ((n == 15) && (BitCount (registers) < 1))
3609                    return false;
3610                break;
3611            default:
3612                return false;
3613        }
3614        // address = R[n] + 4;
3615
3616        int32_t offset = 0;
3617        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3618        if (!success)
3619            return false;
3620
3621        address = address + addr_byte_size;
3622
3623        EmulateInstruction::Context context;
3624        context.type = EmulateInstruction::eContextRegisterStore;
3625        Register base_reg;
3626        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3627
3628        uint32_t lowest_set_bit = 14;
3629        // for i = 0 to 14
3630        for (int i = 0; i < 14; ++i)
3631        {
3632            // if registers<i> == ’1’ then
3633            if (BitIsSet (registers, i))
3634            {
3635                if (i < lowest_set_bit)
3636                    lowest_set_bit = i;
3637                // if i == n && wback && i != LowestSetBit(registers) then
3638                if ((i == n) && wback && (i != lowest_set_bit))
3639                    // MemA[address,4] = bits(32) UNKNOWN;
3640                    WriteBits32UnknownToMemory (address + offset);
3641                // else
3642                else
3643                {
3644                    // MemA[address,4] = R[i];
3645                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3646                    if (!success)
3647                        return false;
3648
3649                    Register data_reg;
3650                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3651                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3652                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3653                        return false;
3654                }
3655
3656                // address = address + 4;
3657                offset += addr_byte_size;
3658            }
3659        }
3660
3661        // if registers<15> == ’1’ then
3662            // MemA[address,4] = PCStoreValue();
3663        if (BitIsSet (registers, 15))
3664        {
3665            Register pc_reg;
3666            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3667            context.SetRegisterPlusOffset (pc_reg, 8);
3668            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3669            if (!success)
3670            return false;
3671
3672            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3673                return false;
3674        }
3675
3676        // if wback then R[n] = R[n] + 4*BitCount(registers);
3677        if (wback)
3678        {
3679            offset = addr_byte_size * BitCount (registers);
3680            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3681            context.SetImmediateSigned (offset);
3682            addr_t data = address + offset;
3683            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3684                return false;
3685        }
3686    }
3687    return true;
3688}
3689
3690// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
3691// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
3692bool
3693EmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding)
3694{
3695#if 0
3696    if ConditionPassed() then
3697        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3698        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3699        address = if index then offset_addr else R[n];
3700        if UnalignedSupport() || address<1:0> == ’00’ then
3701            MemU[address,4] = R[t];
3702        else // Can only occur before ARMv7
3703            MemU[address,4] = bits(32) UNKNOWN;
3704        if wback then R[n] = offset_addr;
3705#endif
3706
3707    bool success = false;
3708    const uint32_t opcode = OpcodeAsUnsigned (&success);
3709    if (!success)
3710        return false;
3711
3712    if (ConditionPassed())
3713    {
3714        const uint32_t addr_byte_size = GetAddressByteSize();
3715
3716        uint32_t t;
3717        uint32_t n;
3718        uint32_t imm32;
3719        bool index;
3720        bool add;
3721        bool wback;
3722        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
3723        switch (encoding)
3724        {
3725            case eEncodingT1:
3726                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32);
3727                t = Bits32 (opcode, 2, 0);
3728                n = Bits32 (opcode, 5, 3);
3729                imm32 = Bits32 (opcode, 10, 6) << 2;
3730
3731                // index = TRUE; add = TRUE; wback = FALSE;
3732                index = true;
3733                add = false;
3734                wback = false;
3735                break;
3736
3737            case eEncodingT2:
3738                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32);
3739                t = Bits32 (opcode, 10, 8);
3740                n = 13;
3741                imm32 = Bits32 (opcode, 7, 0) << 2;
3742
3743                // index = TRUE; add = TRUE; wback = FALSE;
3744                index = true;
3745                add = true;
3746                wback = false;
3747                break;
3748
3749            case eEncodingT3:
3750                // if Rn == ’1111’ then UNDEFINED;
3751                if (Bits32 (opcode, 19, 16) == 15)
3752                    return false;
3753
3754                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3755                t = Bits32 (opcode, 15, 12);
3756                n = Bits32 (opcode, 19, 16);
3757                imm32 = Bits32 (opcode, 11, 0);
3758
3759                // index = TRUE; add = TRUE; wback = FALSE;
3760                index = true;
3761                add = true;
3762                wback = false;
3763
3764                // if t == 15 then UNPREDICTABLE;
3765                if (t == 15)
3766                    return false;
3767                break;
3768
3769            case eEncodingT4:
3770                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT;
3771                // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH;
3772                // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED;
3773                if ((Bits32 (opcode, 19, 16) == 15)
3774                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
3775                    return false;
3776
3777                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3778                t = Bits32 (opcode, 15, 12);
3779                n = Bits32 (opcode, 19, 16);
3780                imm32 = Bits32 (opcode, 7, 0);
3781
3782                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
3783                index = BitIsSet (opcode, 10);
3784                add = BitIsSet (opcode, 9);
3785                wback = BitIsSet (opcode, 8);
3786
3787                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
3788                if ((t == 15) || (wback && (n == t)))
3789                    return false;
3790                break;
3791
3792            default:
3793                return false;
3794        }
3795
3796        addr_t offset_addr;
3797        addr_t address;
3798
3799        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3800        uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3801        if (!success)
3802            return false;
3803
3804        if (add)
3805            offset_addr = base_address + imm32;
3806        else
3807            offset_addr = base_address - imm32;
3808
3809        // address = if index then offset_addr else R[n];
3810        if (index)
3811            address = offset_addr;
3812        else
3813            address = base_address;
3814
3815        EmulateInstruction::Context context;
3816        context.type = eContextRegisterStore;
3817        Register base_reg;
3818        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
3819
3820        // if UnalignedSupport() || address<1:0> == ’00’ then
3821        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
3822        {
3823            // MemU[address,4] = R[t];
3824            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
3825            if (!success)
3826                return false;
3827
3828            Register data_reg;
3829            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
3830            int32_t offset = address - base_address;
3831            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3832            if (!MemUWrite (context, address, data, addr_byte_size))
3833                return false;
3834        }
3835        else
3836        {
3837            // MemU[address,4] = bits(32) UNKNOWN;
3838            WriteBits32UnknownToMemory (address);
3839        }
3840
3841        // if wback then R[n] = offset_addr;
3842        if (wback)
3843        {
3844            context.type = eContextRegisterLoad;
3845            context.SetAddress (offset_addr);
3846            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
3847                return false;
3848        }
3849    }
3850    return true;
3851}
3852
3853// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
3854// word from a register to memory.   The offset register value can optionally be shifted.
3855bool
3856EmulateInstructionARM::EmulateSTRRegister (ARMEncoding encoding)
3857{
3858#if 0
3859    if ConditionPassed() then
3860        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3861        offset = Shift(R[m], shift_t, shift_n, APSR.C);
3862        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
3863        address = if index then offset_addr else R[n];
3864        if t == 15 then // Only possible for encoding A1
3865            data = PCStoreValue();
3866        else
3867            data = R[t];
3868        if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then
3869            MemU[address,4] = data;
3870        else // Can only occur before ARMv7
3871            MemU[address,4] = bits(32) UNKNOWN;
3872        if wback then R[n] = offset_addr;
3873#endif
3874
3875    bool success = false;
3876    const uint32_t opcode = OpcodeAsUnsigned (&success);
3877    if (!success)
3878        return false;
3879
3880    if (ConditionPassed())
3881    {
3882        const uint32_t addr_byte_size = GetAddressByteSize();
3883
3884        uint32_t t;
3885        uint32_t n;
3886        uint32_t m;
3887        ARM_ShifterType shift_t;
3888        uint32_t shift_n;
3889        bool index;
3890        bool add;
3891        bool wback;
3892
3893        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
3894        switch (encoding)
3895        {
3896            case eEncodingT1:
3897                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
3898                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
3899                t = Bits32 (opcode, 2, 0);
3900                n = Bits32 (opcode, 5, 3);
3901                m = Bits32 (opcode, 8, 6);
3902
3903                // index = TRUE; add = TRUE; wback = FALSE;
3904                index = true;
3905                add = true;
3906                wback = false;
3907
3908                // (shift_t, shift_n) = (SRType_LSL, 0);
3909                shift_t = SRType_LSL;
3910                shift_n = 0;
3911                break;
3912
3913            case eEncodingT2:
3914                // if Rn == ’1111’ then UNDEFINED;
3915                if (Bits32 (opcode, 19, 16) == 15)
3916                    return false;
3917
3918                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
3919                t = Bits32 (opcode, 15, 12);
3920                n = Bits32 (opcode, 19, 16);
3921                m = Bits32 (opcode, 3, 0);
3922
3923                // index = TRUE; add = TRUE; wback = FALSE;
3924                index = true;
3925                add = true;
3926                wback = false;
3927
3928                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
3929                shift_t = SRType_LSL;
3930                shift_n = Bits32 (opcode, 5, 4);
3931
3932                // if t == 15 || BadReg(m) then UNPREDICTABLE;
3933                if ((t == 15) || (BadReg (m)))
3934                    return false;
3935                break;
3936
3937            case eEncodingA1:
3938            {
3939                // if P == ’0’ && W == ’1’ then SEE STRT;
3940                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
3941                t = Bits32 (opcode, 15, 12);
3942                n = Bits32 (opcode, 19, 16);
3943                m = Bits32 (opcode, 3, 0);
3944
3945                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
3946                index = BitIsSet (opcode, 24);
3947                add = BitIsSet (opcode, 23);
3948                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
3949
3950                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
3951                uint32_t typ = Bits32 (opcode, 6, 5);
3952                uint32_t imm5 = Bits32 (opcode, 11, 7);
3953                shift_n = DecodeImmShift(typ, imm5, shift_t);
3954
3955                // if m == 15 then UNPREDICTABLE;
3956                if (m == 15)
3957                    return false;
3958
3959                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
3960                if (wback && ((n == 15) || (n == t)))
3961                    return false;
3962
3963                break;
3964            }
3965            default:
3966                return false;
3967        }
3968
3969        addr_t offset_addr;
3970        addr_t address;
3971        int32_t offset = 0;
3972
3973        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3974        if (!success)
3975            return false;
3976
3977        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
3978        if (!success)
3979            return false;
3980
3981        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
3982        offset = Shift (Rm_data, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C));
3983
3984        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
3985        if (add)
3986            offset_addr = base_address + offset;
3987        else
3988            offset_addr = base_address - offset;
3989
3990        // address = if index then offset_addr else R[n];
3991        if (index)
3992            address = offset_addr;
3993        else
3994            address = base_address;
3995
3996        uint32_t data;
3997        // if t == 15 then // Only possible for encoding A1
3998        if (t == 15)
3999            // data = PCStoreValue();
4000            data = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
4001        else
4002            // data = R[t];
4003            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4004
4005        if (!success)
4006            return false;
4007
4008        EmulateInstruction::Context context;
4009        context.type = eContextRegisterStore;
4010
4011        // if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then
4012        if (UnalignedSupport ()
4013            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4014            || CurrentInstrSet() == eModeARM)
4015        {
4016            // MemU[address,4] = data;
4017
4018            Register base_reg;
4019            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4020
4021            Register data_reg;
4022            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4023
4024            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4025            if (!MemUWrite (context, address, data, addr_byte_size))
4026                return false;
4027
4028        }
4029        else
4030            // MemU[address,4] = bits(32) UNKNOWN;
4031            WriteBits32UnknownToMemory (address);
4032
4033        // if wback then R[n] = offset_addr;
4034        if (wback)
4035        {
4036            context.type = eContextRegisterLoad;
4037            context.SetAddress (offset_addr);
4038            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4039                return false;
4040        }
4041
4042    }
4043    return true;
4044}
4045
4046bool
4047EmulateInstructionARM::EmulateSTRBThumb (ARMEncoding encoding)
4048{
4049#if 0
4050    if ConditionPassed() then
4051        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4052        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4053        address = if index then offset_addr else R[n];
4054        MemU[address,1] = R[t]<7:0>;
4055        if wback then R[n] = offset_addr;
4056#endif
4057
4058
4059    bool success = false;
4060    const uint32_t opcode = OpcodeAsUnsigned (&success);
4061    if (!success)
4062        return false;
4063
4064    if (ConditionPassed ())
4065    {
4066        uint32_t t;
4067        uint32_t n;
4068        uint32_t imm32;
4069        bool index;
4070        bool add;
4071        bool wback;
4072        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4073        switch (encoding)
4074        {
4075            case eEncodingT1:
4076                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4077                t = Bits32 (opcode, 2, 0);
4078                n = Bits32 (opcode, 5, 3);
4079                imm32 = Bits32 (opcode, 10, 6);
4080
4081                // index = TRUE; add = TRUE; wback = FALSE;
4082                index = true;
4083                add = true;
4084                wback = false;
4085                break;
4086
4087            case eEncodingT2:
4088                // if Rn == ’1111’ then UNDEFINED;
4089                if (Bits32 (opcode, 19, 16) == 15)
4090                    return false;
4091
4092                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4093                t = Bits32 (opcode, 15, 12);
4094                n = Bits32 (opcode, 19, 16);
4095                imm32 = Bits32 (opcode, 11, 0);
4096
4097                // index = TRUE; add = TRUE; wback = FALSE;
4098                index = true;
4099                add = true;
4100                wback = false;
4101
4102                // if BadReg(t) then UNPREDICTABLE;
4103                if (BadReg (t))
4104                    return false;
4105                break;
4106
4107            case eEncodingT3:
4108                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRBT;
4109                // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED;
4110                if (Bits32 (opcode, 19, 16) == 15)
4111                    return false;
4112
4113                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4114                t = Bits32 (opcode, 15, 12);
4115                n = Bits32 (opcode, 19, 16);
4116                imm32 = Bits32 (opcode, 7, 0);
4117
4118                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
4119                index = BitIsSet (opcode, 10);
4120                add = BitIsSet (opcode, 9);
4121                wback = BitIsSet (opcode, 8);
4122
4123                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4124                if ((BadReg (t)) || (wback && (n == t)))
4125                    return false;
4126                break;
4127
4128            default:
4129                return false;
4130        }
4131
4132        addr_t offset_addr;
4133        addr_t address;
4134        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4135        if (!success)
4136            return false;
4137
4138        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4139        if (add)
4140            offset_addr = base_address + imm32;
4141        else
4142            offset_addr = base_address - imm32;
4143
4144        // address = if index then offset_addr else R[n];
4145        if (index)
4146            address = offset_addr;
4147        else
4148            address = base_address;
4149
4150        // MemU[address,1] = R[t]<7:0>
4151        Register base_reg;
4152        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4153
4154        Register data_reg;
4155        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4156
4157        EmulateInstruction::Context context;
4158        context.type = eContextRegisterStore;
4159        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4160
4161        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4162        if (!success)
4163            return false;
4164
4165        data = Bits32 (data, 7, 0);
4166
4167        if (!MemUWrite (context, address, data, 1))
4168            return false;
4169
4170        // if wback then R[n] = offset_addr;
4171        if (wback)
4172        {
4173            context.type = eContextRegisterLoad;
4174            context.SetAddress (offset_addr);
4175            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4176                return false;
4177        }
4178
4179    }
4180
4181    return true;
4182}
4183
4184// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
4185// from memory, and writes it to a register.  It an use offset, post-indexed, or pre-indexed addressing.
4186bool
4187EmulateInstructionARM::EmulateLDRImmediateARM (ARMEncoding encoding)
4188{
4189#if 0
4190    if ConditionPassed() then
4191        EncodingSpecificOperations();
4192        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4193        address = if index then offset_addr else R[n];
4194        data = MemU[address,4];
4195        if wback then R[n] = offset_addr;
4196        if t == 15 then
4197            if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE;
4198        elsif UnalignedSupport() || address<1:0> = ’00’ then
4199            R[t] = data;
4200        else // Can only apply before ARMv7
4201            R[t] = ROR(data, 8*UInt(address<1:0>));
4202#endif
4203
4204    bool success = false;
4205    const uint32_t opcode = OpcodeAsUnsigned (&success);
4206    if (!success)
4207        return false;
4208
4209    if (ConditionPassed ())
4210    {
4211        const uint32_t addr_byte_size = GetAddressByteSize();
4212
4213        uint32_t t;
4214        uint32_t n;
4215        uint32_t imm32;
4216        bool index;
4217        bool add;
4218        bool wback;
4219
4220        switch (encoding)
4221        {
4222            case eEncodingA1:
4223                // if Rn == ’1111’ then SEE LDR (literal);
4224                // if P == ’0’ && W == ’1’ then SEE LDRT;
4225                // if Rn == ’1101’ && P == ’0’ && U == ’1’ && W == ’0’ && imm12 == ’000000000100’ then SEE POP;
4226                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4227                t = Bits32 (opcode, 15, 12);
4228                n = Bits32 (opcode, 19, 16);
4229                imm32 = Bits32 (opcode, 11, 0);
4230
4231                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
4232                  index = BitIsSet (opcode, 24);
4233                  add = BitIsSet (opcode, 23);
4234                  wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4235
4236                // if wback && n == t then UNPREDICTABLE;
4237                if (wback && (n == t))
4238                    return false;
4239
4240                break;
4241
4242            default:
4243                return false;
4244        }
4245
4246        addr_t address;
4247        addr_t offset_addr;
4248        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4249        if (!success)
4250            return false;
4251
4252        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4253        if (add)
4254                  offset_addr = base_address + imm32;
4255        else
4256            offset_addr = base_address - imm32;
4257
4258        // address = if index then offset_addr else R[n];
4259        if (index)
4260            address = offset_addr;
4261        else
4262            address = base_address;
4263
4264        // data = MemU[address,4];
4265
4266        Register base_reg;
4267        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4268
4269        EmulateInstruction::Context context;
4270        context.type = eContextRegisterLoad;
4271        context.SetRegisterPlusOffset (base_reg, address - base_address);
4272
4273        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
4274        if (!success)
4275            return false;
4276
4277        // if wback then R[n] = offset_addr;
4278        if (wback)
4279        {
4280            context.type = eContextAdjustBaseRegister;
4281            context.SetAddress (offset_addr);
4282            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4283                return false;
4284        }
4285
4286        // if t == 15 then
4287        if (t == 15)
4288        {
4289            // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE;
4290            if (BitIsClear (address, 1) && BitIsClear (address, 0))
4291            {
4292                // LoadWritePC (data);
4293                context.type = eContextRegisterLoad;
4294                context.SetRegisterPlusOffset (base_reg, address - base_address);
4295                LoadWritePC (context, data);
4296            }
4297            else
4298                  return false;
4299        }
4300        // elsif UnalignedSupport() || address<1:0> = ’00’ then
4301        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4302        {
4303            // R[t] = data;
4304            context.type = eContextRegisterLoad;
4305            context.SetRegisterPlusOffset (base_reg, address - base_address);
4306            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
4307                return false;
4308        }
4309        // else // Can only apply before ARMv7
4310        else
4311        {
4312            // R[t] = ROR(data, 8*UInt(address<1:0>));
4313            data = ROR (data, Bits32 (address, 1, 0));
4314            context.type = eContextRegisterLoad;
4315            context.SetImmediate (data);
4316            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
4317                return false;
4318        }
4319
4320    }
4321    return true;
4322}
4323
4324EmulateInstructionARM::ARMOpcode*
4325EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
4326{
4327    static ARMOpcode
4328    g_arm_opcodes[] =
4329    {
4330        //----------------------------------------------------------------------
4331        // Prologue instructions
4332        //----------------------------------------------------------------------
4333
4334        // push register(s)
4335        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
4336        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
4337
4338        // set r7 to point to a stack offset
4339        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
4340        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
4341        // copy the stack pointer to ip
4342        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
4343        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
4344        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
4345
4346        // adjust the stack pointer
4347        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
4348
4349        // push one register
4350        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
4351        { 0x0fff0000, 0x052d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
4352
4353        // vector push consecutive extension register(s)
4354        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
4355        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
4356
4357        //----------------------------------------------------------------------
4358        // Epilogue instructions
4359        //----------------------------------------------------------------------
4360
4361        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
4362        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
4363        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
4364        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
4365
4366        //----------------------------------------------------------------------
4367        // Supervisor Call (previously Software Interrupt)
4368        //----------------------------------------------------------------------
4369        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
4370
4371        //----------------------------------------------------------------------
4372        // Branch instructions
4373        //----------------------------------------------------------------------
4374        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"},
4375        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
4376        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
4377        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
4378        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
4379        // for example, "bx lr"
4380        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
4381
4382        //----------------------------------------------------------------------
4383        // Data-processing instructions
4384        //----------------------------------------------------------------------
4385        // move bitwise not
4386        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNRdImm, "mvn{s} <Rd>, #<const>"},
4387        // asr (immediate)
4388        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
4389        // asr (register)
4390        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
4391        // lsl (immediate)
4392        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
4393        // lsl (register)
4394        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
4395        // lsr (immediate)
4396        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
4397        // lsr (register)
4398        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
4399        // rrx is a special case encoding of ror (immediate)
4400        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
4401        // ror (immediate)
4402        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
4403        // ror (register)
4404        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
4405
4406        //----------------------------------------------------------------------
4407        // Load instructions
4408        //----------------------------------------------------------------------
4409        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
4410        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
4411        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
4412        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
4413        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
4414
4415        //----------------------------------------------------------------------
4416        // Store instructions
4417        //----------------------------------------------------------------------
4418        { 0x0fd00000, 0x08800000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
4419        { 0x0fd00000, 0x08000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
4420        { 0x0fd00000, 0x09000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
4421        { 0x0fd00000, 0x09800000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
4422        { 0x0e500010, 0x06000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }
4423
4424
4425    };
4426    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
4427
4428    for (size_t i=0; i<k_num_arm_opcodes; ++i)
4429    {
4430        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
4431            return &g_arm_opcodes[i];
4432    }
4433    return NULL;
4434}
4435
4436
4437EmulateInstructionARM::ARMOpcode*
4438EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
4439{
4440
4441    static ARMOpcode
4442    g_thumb_opcodes[] =
4443    {
4444        //----------------------------------------------------------------------
4445        // Prologue instructions
4446        //----------------------------------------------------------------------
4447
4448        // push register(s)
4449        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
4450        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
4451        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
4452
4453        // set r7 to point to a stack offset
4454        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
4455        // copy the stack pointer to r7
4456        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
4457        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
4458        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
4459
4460        // PC-relative load into register (see also EmulateADDSPRm)
4461        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
4462
4463        // adjust the stack pointer
4464        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
4465        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "add sp, sp, #imm"},
4466        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
4467        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
4468
4469        // vector push consecutive extension register(s)
4470        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
4471        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
4472
4473        //----------------------------------------------------------------------
4474        // Epilogue instructions
4475        //----------------------------------------------------------------------
4476
4477        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
4478        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
4479        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
4480        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
4481        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
4482        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
4483
4484        //----------------------------------------------------------------------
4485        // Supervisor Call (previously Software Interrupt)
4486        //----------------------------------------------------------------------
4487        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
4488
4489        //----------------------------------------------------------------------
4490        // If Then makes up to four following instructions conditional.
4491        //----------------------------------------------------------------------
4492        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
4493
4494        //----------------------------------------------------------------------
4495        // Branch instructions
4496        //----------------------------------------------------------------------
4497        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
4498        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
4499        { 0xffff8000, 0x0000e000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"},
4500        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
4501        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"},
4502        // J1 == J2 == 1
4503        { 0xf800f800, 0xf000f800, ARMV4T_ABOVE,  eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
4504        // J1 == J2 == 1
4505        { 0xf800e800, 0xf000e800, ARMV5_ABOVE,   eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
4506        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
4507        // for example, "bx lr"
4508        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
4509        // compare and branch
4510        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
4511        // table branch byte
4512        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
4513        // table branch halfword
4514        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
4515
4516        //----------------------------------------------------------------------
4517        // Data-processing instructions
4518        //----------------------------------------------------------------------
4519        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
4520        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
4521        // Can update PC!
4522        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
4523        // move from high register to high register
4524        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
4525        // move from low register to low register
4526        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
4527        // move immediate
4528        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
4529        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
4530        // move bitwise not
4531        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNRdImm, "mvn{s} <Rd>, #<const>"},
4532        // compare a register with immediate
4533        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPRnImm, "cmp<c> <Rn>, #imm8"},
4534        // compare Rn with Rm (Rn and Rm both from r0-r7)
4535        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPRnRm, "cmp<c> <Rn>, <Rm>"},
4536        // compare Rn with Rm (Rn and Rm not both from r0-r7)
4537        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPRnRm, "cmp<c> <Rn>, <Rm>"},
4538        // asr (immediate)
4539        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
4540        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
4541        // asr (register)
4542        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
4543        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
4544        // lsl (immediate)
4545        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
4546        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
4547        // lsl (register)
4548        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
4549        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
4550        // lsr (immediate)
4551        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
4552        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
4553        // lsr (register)
4554        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
4555        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
4556        // rrx is a special case encoding of ror (immediate)
4557        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
4558        // ror (immediate)
4559        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
4560        // ror (register)
4561        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
4562        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
4563
4564        //----------------------------------------------------------------------
4565        // Load instructions
4566        //----------------------------------------------------------------------
4567        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
4568        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
4569        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
4570        { 0xfffff800, 0x00006800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
4571        // Thumb2 PC-relative load into register
4572        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
4573
4574        //----------------------------------------------------------------------
4575        // Store instructions
4576        //----------------------------------------------------------------------
4577        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
4578        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
4579        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
4580        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>{,#<imm>}]" },
4581        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [SP,#<imm>]" },
4582        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt [<Rn>,#<imm12>]" },
4583        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>,#+/-<imm8>]" },
4584        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> {<Rn> <Rm>]" },
4585        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt> [<Rn> <Rm> {lsl #imm2>}]" },
4586        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> [<Rn> #<imm5>]" },
4587        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt> [<Rn> #<imm12>]" },
4588        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> [<Rn>, #+/-<imm8>]{!}" }
4589    };
4590
4591    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
4592    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
4593    {
4594        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
4595            return &g_thumb_opcodes[i];
4596    }
4597    return NULL;
4598}
4599
4600bool
4601EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
4602{
4603    m_arm_isa = 0;
4604    const char *arch_cstr = arch.AsCString ();
4605    if (arch_cstr)
4606    {
4607        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
4608        else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
4609        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
4610        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
4611        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
4612        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
4613        else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
4614        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
4615        else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
4616        else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
4617    }
4618    return m_arm_isa != 0;
4619}
4620
4621
4622bool
4623EmulateInstructionARM::ReadInstruction ()
4624{
4625    bool success = false;
4626    m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
4627    if (success)
4628    {
4629        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
4630        if (success)
4631        {
4632            Context read_inst_context;
4633            read_inst_context.type = eContextReadOpcode;
4634            read_inst_context.SetNoArgs ();
4635
4636            if (m_inst_cpsr & MASK_CPSR_T)
4637            {
4638                m_inst_mode = eModeThumb;
4639                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
4640
4641                if (success)
4642                {
4643                    if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0))
4644                    {
4645                        m_inst.opcode_type = eOpcode16;
4646                        m_inst.opcode.inst16 = thumb_opcode;
4647                    }
4648                    else
4649                    {
4650                        m_inst.opcode_type = eOpcode32;
4651                        m_inst.opcode.inst32 = (thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success);
4652                    }
4653                }
4654            }
4655            else
4656            {
4657                m_inst_mode = eModeARM;
4658                m_inst.opcode_type = eOpcode32;
4659                m_inst.opcode.inst32 = MemARead(read_inst_context, pc, 4, 0, &success);
4660            }
4661        }
4662    }
4663    if (!success)
4664    {
4665        m_inst_mode = eModeInvalid;
4666        m_inst_pc = LLDB_INVALID_ADDRESS;
4667    }
4668    return success;
4669}
4670
4671uint32_t
4672EmulateInstructionARM::ArchVersion ()
4673{
4674    return m_arm_isa;
4675}
4676
4677bool
4678EmulateInstructionARM::ConditionPassed ()
4679{
4680    if (m_inst_cpsr == 0)
4681        return false;
4682
4683    const uint32_t cond = CurrentCond ();
4684
4685    if (cond == UINT32_MAX)
4686        return false;
4687
4688    bool result = false;
4689    switch (UnsignedBits(cond, 3, 1))
4690    {
4691    case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break;
4692    case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break;
4693    case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break;
4694    case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break;
4695    case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break;
4696    case 5:
4697        {
4698            bool n = (m_inst_cpsr & MASK_CPSR_N);
4699            bool v = (m_inst_cpsr & MASK_CPSR_V);
4700            result = n == v;
4701        }
4702        break;
4703    case 6:
4704        {
4705            bool n = (m_inst_cpsr & MASK_CPSR_N);
4706            bool v = (m_inst_cpsr & MASK_CPSR_V);
4707            result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0);
4708        }
4709        break;
4710    case 7:
4711        result = true;
4712        break;
4713    }
4714
4715    if (cond & 1)
4716        result = !result;
4717    return result;
4718}
4719
4720uint32_t
4721EmulateInstructionARM::CurrentCond ()
4722{
4723    switch (m_inst_mode)
4724    {
4725    default:
4726    case eModeInvalid:
4727        break;
4728
4729    case eModeARM:
4730        return UnsignedBits(m_inst.opcode.inst32, 31, 28);
4731
4732    case eModeThumb:
4733        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
4734        // 'cond' field of the encoding.
4735        if (m_inst.opcode_type == eOpcode16 &&
4736            Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d &&
4737            Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f)
4738        {
4739            return Bits32(m_inst.opcode.inst16, 11, 7);
4740        }
4741        else if (m_inst.opcode_type == eOpcode32 &&
4742                 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e &&
4743                 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 &&
4744                 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 &&
4745                 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d)
4746        {
4747            return Bits32(m_inst.opcode.inst32, 25, 22);
4748        }
4749
4750        return m_it_session.GetCond();
4751    }
4752    return UINT32_MAX;  // Return invalid value
4753}
4754
4755bool
4756EmulateInstructionARM::InITBlock()
4757{
4758    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
4759}
4760
4761bool
4762EmulateInstructionARM::LastInITBlock()
4763{
4764    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
4765}
4766
4767bool
4768EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
4769{
4770    addr_t target;
4771
4772    // Check the current instruction set.
4773    if (CurrentInstrSet() == eModeARM)
4774        target = addr & 0xfffffffc;
4775    else
4776        target = addr & 0xfffffffe;
4777
4778    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
4779        return false;
4780
4781    return true;
4782}
4783
4784// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
4785bool
4786EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
4787{
4788    addr_t target;
4789    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
4790    // we want to record it and issue a WriteRegister callback so the clients
4791    // can track the mode changes accordingly.
4792    bool cpsr_changed = false;
4793
4794    if (BitIsSet(addr, 0))
4795    {
4796        if (CurrentInstrSet() != eModeThumb)
4797        {
4798            SelectInstrSet(eModeThumb);
4799            cpsr_changed = true;
4800        }
4801        target = addr & 0xfffffffe;
4802        context.SetMode (eModeThumb);
4803    }
4804    else if (BitIsClear(addr, 1))
4805    {
4806        if (CurrentInstrSet() != eModeARM)
4807        {
4808            SelectInstrSet(eModeARM);
4809            cpsr_changed = true;
4810        }
4811        target = addr & 0xfffffffc;
4812        context.SetMode (eModeARM);
4813    }
4814    else
4815        return false; // address<1:0> == '10' => UNPREDICTABLE
4816
4817    if (cpsr_changed)
4818    {
4819        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
4820            return false;
4821    }
4822    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
4823        return false;
4824
4825    return true;
4826}
4827
4828// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
4829bool
4830EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
4831{
4832    if (ArchVersion() >= ARMv5T)
4833        return BXWritePC(context, addr);
4834    else
4835        return BranchWritePC((const Context)context, addr);
4836}
4837
4838// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
4839bool
4840EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
4841{
4842    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
4843        return BXWritePC(context, addr);
4844    else
4845        return BranchWritePC((const Context)context, addr);
4846}
4847
4848EmulateInstructionARM::Mode
4849EmulateInstructionARM::CurrentInstrSet ()
4850{
4851    return m_inst_mode;
4852}
4853
4854// Set the 'T' bit of our CPSR.  The m_inst_mode gets updated when the next
4855// ReadInstruction() is performed.  This function has a side effect of updating
4856// the m_new_inst_cpsr member variable if necessary.
4857bool
4858EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
4859{
4860    m_new_inst_cpsr = m_inst_cpsr;
4861    switch (arm_or_thumb)
4862    {
4863    default:
4864        return false;
4865    eModeARM:
4866        // Clear the T bit.
4867        m_new_inst_cpsr &= ~MASK_CPSR_T;
4868        break;
4869    eModeThumb:
4870        // Set the T bit.
4871        m_new_inst_cpsr |= MASK_CPSR_T;
4872        break;
4873    }
4874    return true;
4875}
4876
4877// This function returns TRUE if the processor currently provides support for
4878// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
4879// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
4880bool
4881EmulateInstructionARM::UnalignedSupport()
4882{
4883    return (ArchVersion() >= ARMv7);
4884}
4885
4886// The main addition and subtraction instructions can produce status information
4887// about both unsigned carry and signed overflow conditions.  This status
4888// information can be used to synthesize multi-word additions and subtractions.
4889EmulateInstructionARM::AddWithCarryResult
4890EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
4891{
4892    uint32_t result;
4893    uint8_t carry_out;
4894    uint8_t overflow;
4895
4896    uint64_t unsigned_sum = x + y + carry_in;
4897    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
4898
4899    result = UnsignedBits(unsigned_sum, 31, 0);
4900    carry_out = (result == unsigned_sum ? 0 : 1);
4901    overflow = ((int32_t)result == signed_sum ? 0 : 1);
4902
4903    AddWithCarryResult res = { result, carry_out, overflow };
4904    return res;
4905}
4906
4907// Write the result to the ARM core register Rd, and optionally update the
4908// condition flags based on the result.
4909//
4910// This helper method tries to encapsulate the following pseudocode from the
4911// ARM Architecture Reference Manual:
4912//
4913// if d == 15 then         // Can only occur for encoding A1
4914//     ALUWritePC(result); // setflags is always FALSE here
4915// else
4916//     R[d] = result;
4917//     if setflags then
4918//         APSR.N = result<31>;
4919//         APSR.Z = IsZeroBit(result);
4920//         APSR.C = carry;
4921//         // APSR.V unchanged
4922//
4923// In the above case, the API client does not pass in the overflow arg, which
4924// defaults to ~0u.
4925bool
4926EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
4927                                                  const uint32_t result,
4928                                                  const uint32_t Rd,
4929                                                  bool setflags,
4930                                                  const uint32_t carry,
4931                                                  const uint32_t overflow)
4932{
4933    if (Rd == 15)
4934    {
4935        if (!ALUWritePC (context, result))
4936            return false;
4937    }
4938    else
4939    {
4940        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result))
4941            return false;
4942        if (setflags)
4943            return WriteFlags (context, result, carry, overflow);
4944    }
4945    return true;
4946}
4947
4948// This helper method tries to encapsulate the following pseudocode from the
4949// ARM Architecture Reference Manual:
4950//
4951// APSR.N = result<31>;
4952// APSR.Z = IsZeroBit(result);
4953// APSR.C = carry;
4954// APSR.V = overflow
4955//
4956// Default arguments can be specified for carry and overflow parameters, which means
4957// not to update the respective flags.
4958bool
4959EmulateInstructionARM::WriteFlags (Context &context,
4960                                   const uint32_t result,
4961                                   const uint32_t carry,
4962                                   const uint32_t overflow)
4963{
4964    m_new_inst_cpsr = m_inst_cpsr;
4965    SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N));
4966    SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0);
4967    if (carry != ~0u)
4968        SetBit32(m_new_inst_cpsr, CPSR_C, carry);
4969    if (overflow != ~0u)
4970        SetBit32(m_new_inst_cpsr, CPSR_V, overflow);
4971    if (m_new_inst_cpsr != m_inst_cpsr)
4972    {
4973        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
4974            return false;
4975    }
4976    return true;
4977}
4978
4979bool
4980EmulateInstructionARM::EvaluateInstruction ()
4981{
4982    // Advance the ITSTATE bits to their values for the next instruction.
4983    if (m_inst_mode == eModeThumb && m_it_session.InITBlock())
4984        m_it_session.ITAdvance();
4985
4986    return false;
4987}
4988