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