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