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