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