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