EmulateInstructionARM.cpp revision d4dc4444e124b290cbe30cdaade7e97161fa47c8
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 "EmulateInstructionARM.h"
11#include "lldb/Core/ConstString.h"
12
13#include "Plugins/Process/Utility/ARMDefines.h"
14#include "Plugins/Process/Utility/ARMUtils.h"
15#include "Utility/ARM_DWARF_Registers.h"
16
17#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
18                                     // and CountTrailingZeros_32 function
19
20using namespace lldb;
21using namespace lldb_private;
22
23static inline uint32_t Align(uint32_t val, uint32_t alignment)
24{
25    return alignment * (val / alignment);
26}
27
28//----------------------------------------------------------------------
29//
30// ITSession implementation
31//
32//----------------------------------------------------------------------
33
34// A8.6.50
35// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
36static unsigned short CountITSize(unsigned ITMask) {
37    // First count the trailing zeros of the IT mask.
38    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
39    if (TZ > 3)
40    {
41        printf("Encoding error: IT Mask '0000'\n");
42        return 0;
43    }
44    return (4 - TZ);
45}
46
47// Init ITState.  Note that at least one bit is always 1 in mask.
48bool ITSession::InitIT(unsigned short bits7_0)
49{
50    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
51    if (ITCounter == 0)
52        return false;
53
54    // A8.6.50 IT
55    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
56    if (FirstCond == 0xF)
57    {
58        printf("Encoding error: IT FirstCond '1111'\n");
59        return false;
60    }
61    if (FirstCond == 0xE && ITCounter != 1)
62    {
63        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
64        return false;
65    }
66
67    ITState = bits7_0;
68    return true;
69}
70
71// Update ITState if necessary.
72void ITSession::ITAdvance()
73{
74    assert(ITCounter);
75    --ITCounter;
76    if (ITCounter == 0)
77        ITState = 0;
78    else
79    {
80        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
81        SetBits32(ITState, 4, 0, NewITState4_0);
82    }
83}
84
85// Return true if we're inside an IT Block.
86bool ITSession::InITBlock()
87{
88    return ITCounter != 0;
89}
90
91// Return true if we're the last instruction inside an IT Block.
92bool ITSession::LastInITBlock()
93{
94    return ITCounter == 1;
95}
96
97// Get condition bits for the current thumb instruction.
98uint32_t ITSession::GetCond()
99{
100    if (InITBlock())
101        return Bits32(ITState, 7, 4);
102    else
103        return COND_AL;
104}
105
106// ARM constants used during decoding
107#define REG_RD          0
108#define LDM_REGLIST     1
109#define PC_REG          15
110#define PC_REGLIST_BIT  0x8000
111
112#define ARMv4     (1u << 0)
113#define ARMv4T    (1u << 1)
114#define ARMv5T    (1u << 2)
115#define ARMv5TE   (1u << 3)
116#define ARMv5TEJ  (1u << 4)
117#define ARMv6     (1u << 5)
118#define ARMv6K    (1u << 6)
119#define ARMv6T2   (1u << 7)
120#define ARMv7     (1u << 8)
121#define ARMv8     (1u << 9)
122#define ARMvAll   (0xffffffffu)
123
124#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
125#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
126#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
127
128//----------------------------------------------------------------------
129//
130// EmulateInstructionARM implementation
131//
132//----------------------------------------------------------------------
133
134void
135EmulateInstructionARM::Initialize ()
136{
137}
138
139void
140EmulateInstructionARM::Terminate ()
141{
142}
143
144// Push Multiple Registers stores multiple registers to the stack, storing to
145// consecutive memory locations ending just below the address in SP, and updates
146// SP to point to the start of the stored data.
147bool
148EmulateInstructionARM::EmulatePush (ARMEncoding encoding)
149{
150#if 0
151    // ARM pseudo code...
152    if (ConditionPassed())
153    {
154        EncodingSpecificOperations();
155        NullCheckIfThumbEE(13);
156        address = SP - 4*BitCount(registers);
157
158        for (i = 0 to 14)
159        {
160            if (registers<i> == ’1’)
161            {
162                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
163                    MemA[address,4] = bits(32) UNKNOWN;
164                else
165                    MemA[address,4] = R[i];
166                address = address + 4;
167            }
168        }
169
170        if (registers<15> == ’1’) // Only possible for encoding A1 or A2
171            MemA[address,4] = PCStoreValue();
172
173        SP = SP - 4*BitCount(registers);
174    }
175#endif
176
177    bool success = false;
178    const uint32_t opcode = OpcodeAsUnsigned (&success);
179    if (!success)
180        return false;
181
182    if (ConditionPassed())
183    {
184        const uint32_t addr_byte_size = GetAddressByteSize();
185        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
186        if (!success)
187            return false;
188        uint32_t registers = 0;
189        uint32_t Rt; // the source register
190        switch (encoding) {
191        case eEncodingT1:
192            registers = Bits32(opcode, 7, 0);
193            // The M bit represents LR.
194            if (Bit32(opcode, 8))
195                registers |= (1u << 14);
196            // if BitCount(registers) < 1 then UNPREDICTABLE;
197            if (BitCount(registers) < 1)
198                return false;
199            break;
200        case eEncodingT2:
201            // Ignore bits 15 & 13.
202            registers = Bits32(opcode, 15, 0) & ~0xa000;
203            // if BitCount(registers) < 2 then UNPREDICTABLE;
204            if (BitCount(registers) < 2)
205                return false;
206            break;
207        case eEncodingT3:
208            Rt = Bits32(opcode, 15, 12);
209            // if BadReg(t) then UNPREDICTABLE;
210            if (BadReg(Rt))
211                return false;
212            registers = (1u << Rt);
213            break;
214        case eEncodingA1:
215            registers = Bits32(opcode, 15, 0);
216            // Instead of return false, let's handle the following case as well,
217            // which amounts to pushing one reg onto the full descending stacks.
218            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
219            break;
220        case eEncodingA2:
221            Rt = Bits32(opcode, 15, 12);
222            // if t == 13 then UNPREDICTABLE;
223            if (Rt == dwarf_sp)
224                return false;
225            registers = (1u << Rt);
226            break;
227        default:
228            return false;
229        }
230        addr_t sp_offset = addr_byte_size * BitCount (registers);
231        addr_t addr = sp - sp_offset;
232        uint32_t i;
233
234        EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 };
235        for (i=0; i<15; ++i)
236        {
237            if (BitIsSet (registers, i))
238            {
239                context.arg1 = dwarf_r0 + i;    // arg1 in the context is the DWARF register number
240                context.arg2 = addr - sp;       // arg2 in the context is the stack pointer offset
241                uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success);
242                if (!success)
243                    return false;
244                if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size))
245                    return false;
246                addr += addr_byte_size;
247            }
248        }
249
250        if (BitIsSet (registers, 15))
251        {
252            context.arg1 = dwarf_pc;    // arg1 in the context is the DWARF register number
253            context.arg2 = addr - sp;   // arg2 in the context is the stack pointer offset
254            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
255            if (!success)
256                return false;
257            if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size))
258                return false;
259        }
260
261        context.type = EmulateInstruction::eContextAdjustStackPointer;
262        context.arg0 = eRegisterKindGeneric;
263        context.arg1 = LLDB_REGNUM_GENERIC_SP;
264        context.arg2 = -sp_offset;
265
266        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
267            return false;
268    }
269    return true;
270}
271
272// Pop Multiple Registers loads multiple registers from the stack, loading from
273// consecutive memory locations staring at the address in SP, and updates
274// SP to point just above the loaded data.
275bool
276EmulateInstructionARM::EmulatePop (ARMEncoding encoding)
277{
278#if 0
279    // ARM pseudo code...
280    if (ConditionPassed())
281    {
282        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
283        address = SP;
284        for i = 0 to 14
285            if registers<i> == ‘1then
286                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
287        if registers<15> == ‘1then
288            if UnalignedAllowed then
289                LoadWritePC(MemU[address,4]);
290            else
291                LoadWritePC(MemA[address,4]);
292        if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers);
293        if registers<13> == ‘1then SP = bits(32) UNKNOWN;
294    }
295#endif
296
297    bool success = false;
298    const uint32_t opcode = OpcodeAsUnsigned (&success);
299    if (!success)
300        return false;
301
302    if (ConditionPassed())
303    {
304        const uint32_t addr_byte_size = GetAddressByteSize();
305        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
306        if (!success)
307            return false;
308        uint32_t registers = 0;
309        uint32_t Rt; // the destination register
310        switch (encoding) {
311        case eEncodingT1:
312            registers = Bits32(opcode, 7, 0);
313            // The P bit represents PC.
314            if (Bit32(opcode, 8))
315                registers |= (1u << 15);
316            // if BitCount(registers) < 1 then UNPREDICTABLE;
317            if (BitCount(registers) < 1)
318                return false;
319            break;
320        case eEncodingT2:
321            // Ignore bit 13.
322            registers = Bits32(opcode, 15, 0) & ~0x2000;
323            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
324            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
325                return false;
326            break;
327        case eEncodingT3:
328            Rt = Bits32(opcode, 15, 12);
329            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
330            if (Rt == dwarf_sp)
331                return false;
332            registers = (1u << Rt);
333            break;
334        case eEncodingA1:
335            registers = Bits32(opcode, 15, 0);
336            // Instead of return false, let's handle the following case as well,
337            // which amounts to popping one reg from the full descending stacks.
338            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
339
340            // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE;
341            if (Bit32(opcode, 13) && ArchVersion() >= ARMv7)
342                return false;
343            break;
344        case eEncodingA2:
345            Rt = Bits32(opcode, 15, 12);
346            // if t == 13 then UNPREDICTABLE;
347            if (Rt == dwarf_sp)
348                return false;
349            registers = (1u << Rt);
350            break;
351        default:
352            return false;
353        }
354        addr_t sp_offset = addr_byte_size * BitCount (registers);
355        addr_t addr = sp;
356        uint32_t i, data;
357
358        EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 };
359        for (i=0; i<15; ++i)
360        {
361            if (BitIsSet (registers, i))
362            {
363                context.arg1 = dwarf_r0 + i;    // arg1 in the context is the DWARF register number
364                context.arg2 = addr - sp;       // arg2 in the context is the stack pointer offset
365                data = ReadMemoryUnsigned(context, addr, 4, 0, &success);
366                if (!success)
367                    return false;
368                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data))
369                    return false;
370                addr += addr_byte_size;
371            }
372        }
373
374        if (BitIsSet (registers, 15))
375        {
376            context.arg1 = dwarf_pc;    // arg1 in the context is the DWARF register number
377            context.arg2 = addr - sp;   // arg2 in the context is the stack pointer offset
378            data = ReadMemoryUnsigned(context, addr, 4, 0, &success);
379            if (!success)
380                return false;
381            // In ARMv5T and above, this is an interworking branch.
382            if (!LoadWritePC(context, data))
383                return false;
384            addr += addr_byte_size;
385        }
386
387        context.type = EmulateInstruction::eContextAdjustStackPointer;
388        context.arg0 = eRegisterKindGeneric;
389        context.arg1 = LLDB_REGNUM_GENERIC_SP;
390        context.arg2 = sp_offset;
391
392        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
393            return false;
394    }
395    return true;
396}
397
398// Set r7 or ip to point to saved value residing within the stack.
399// ADD (SP plus immediate)
400bool
401EmulateInstructionARM::EmulateAddRdSPImmediate (ARMEncoding encoding)
402{
403#if 0
404    // ARM pseudo code...
405    if (ConditionPassed())
406    {
407        EncodingSpecificOperations();
408        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
409        if d == 15 then
410           ALUWritePC(result); // setflags is always FALSE here
411        else
412            R[d] = result;
413            if setflags then
414                APSR.N = result<31>;
415                APSR.Z = IsZeroBit(result);
416                APSR.C = carry;
417                APSR.V = overflow;
418    }
419#endif
420
421    bool success = false;
422    const uint32_t opcode = OpcodeAsUnsigned (&success);
423    if (!success)
424        return false;
425
426    if (ConditionPassed())
427    {
428        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
429        if (!success)
430            return false;
431        uint32_t Rd; // the destination register
432        uint32_t imm32;
433        switch (encoding) {
434        case eEncodingT1:
435            Rd = 7;
436            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
437            break;
438        case eEncodingA1:
439            Rd = Bits32(opcode, 15, 12);
440            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
441            break;
442        default:
443            return false;
444        }
445        addr_t sp_offset = imm32;
446        addr_t addr = sp + sp_offset; // a pointer to the stack area
447
448        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
449                                                eRegisterKindGeneric,
450                                                LLDB_REGNUM_GENERIC_SP,
451                                                sp_offset };
452
453        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
454            return false;
455    }
456    return true;
457}
458
459// Set r7 or ip to the current stack pointer.
460// MOV (register)
461bool
462EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding)
463{
464#if 0
465    // ARM pseudo code...
466    if (ConditionPassed())
467    {
468        EncodingSpecificOperations();
469        result = R[m];
470        if d == 15 then
471            ALUWritePC(result); // setflags is always FALSE here
472        else
473            R[d] = result;
474            if setflags then
475                APSR.N = result<31>;
476                APSR.Z = IsZeroBit(result);
477                // APSR.C unchanged
478                // APSR.V unchanged
479    }
480#endif
481
482    bool success = false;
483    //const uint32_t opcode = OpcodeAsUnsigned (&success);
484    //if (!success)
485    //    return false;
486
487    if (ConditionPassed())
488    {
489        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
490        if (!success)
491            return false;
492        uint32_t Rd; // the destination register
493        switch (encoding) {
494        case eEncodingT1:
495            Rd = 7;
496            break;
497        case eEncodingA1:
498            Rd = 12;
499            break;
500        default:
501            return false;
502        }
503        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
504                                                eRegisterKindGeneric,
505                                                LLDB_REGNUM_GENERIC_SP,
506                                                0 };
507
508        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
509            return false;
510    }
511    return true;
512}
513
514// Move from high register (r8-r15) to low register (r0-r7).
515// MOV (register)
516bool
517EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding)
518{
519    return EmulateMovRdRm (encoding);
520}
521
522// Move from register to register.
523// MOV (register)
524bool
525EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding)
526{
527#if 0
528    // ARM pseudo code...
529    if (ConditionPassed())
530    {
531        EncodingSpecificOperations();
532        result = R[m];
533        if d == 15 then
534            ALUWritePC(result); // setflags is always FALSE here
535        else
536            R[d] = result;
537            if setflags then
538                APSR.N = result<31>;
539                APSR.Z = IsZeroBit(result);
540                // APSR.C unchanged
541                // APSR.V unchanged
542    }
543#endif
544
545    bool success = false;
546    const uint32_t opcode = OpcodeAsUnsigned (&success);
547    if (!success)
548        return false;
549
550    if (ConditionPassed())
551    {
552        uint32_t Rm; // the source register
553        uint32_t Rd; // the destination register
554        bool setflags;
555        switch (encoding) {
556        case eEncodingT1:
557            Rm = Bits32(opcode, 6, 3);
558            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1);
559            setflags = false;
560            break;
561        case eEncodingT2:
562            Rm = Bits32(opcode, 5, 3);
563            Rd = Bits32(opcode, 2, 1);
564            setflags = true;
565            break;
566        default:
567            return false;
568        }
569        uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
570        if (!success)
571            return false;
572
573        // The context specifies that Rm is to be moved into Rd.
574        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
575                                                eRegisterKindDWARF,
576                                                dwarf_r0 + Rm,
577                                                0 };
578
579        if (Rd == 15)
580        {
581            if (!ALUWritePC (context, reg_value))
582                return false;
583        }
584        else
585        {
586            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value))
587                return false;
588            if (setflags)
589            {
590                m_new_inst_cpsr = m_inst_cpsr;
591                SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(reg_value, CPSR_N));
592                SetBit32(m_new_inst_cpsr, CPSR_Z, reg_value == 0 ? 1 : 0);
593                if (m_new_inst_cpsr != m_inst_cpsr)
594                {
595                    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
596                        return false;
597                }
598            }
599        }
600    }
601    return true;
602}
603
604// PC relative immediate load into register, possibly followed by ADD (SP plus register).
605// LDR (literal)
606bool
607EmulateInstructionARM::EmulateLDRRdPCRelative (ARMEncoding encoding)
608{
609#if 0
610    // ARM pseudo code...
611    if (ConditionPassed())
612    {
613        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
614        base = Align(PC,4);
615        address = if add then (base + imm32) else (base - imm32);
616        data = MemU[address,4];
617        if t == 15 then
618            if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE;
619        elsif UnalignedSupport() || address<1:0> = ‘00’ then
620            R[t] = data;
621        else // Can only apply before ARMv7
622            if CurrentInstrSet() == InstrSet_ARM then
623                R[t] = ROR(data, 8*UInt(address<1:0>));
624            else
625                R[t] = bits(32) UNKNOWN;
626    }
627#endif
628
629    bool success = false;
630    const uint32_t opcode = OpcodeAsUnsigned (&success);
631    if (!success)
632        return false;
633
634    if (ConditionPassed())
635    {
636        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
637        if (!success)
638            return false;
639
640        // PC relative immediate load context
641        EmulateInstruction::Context context = {EmulateInstruction::eContextRegisterPlusOffset,
642                                               eRegisterKindGeneric,
643                                               LLDB_REGNUM_GENERIC_PC,
644                                               0};
645        uint32_t Rd; // the destination register
646        uint32_t imm32; // immediate offset from the PC
647        addr_t addr;    // the PC relative address
648        uint32_t data;  // the literal data value from the PC relative load
649        switch (encoding) {
650        case eEncodingT1:
651            Rd = Bits32(opcode, 10, 8);
652            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
653            addr = pc + 4 + imm32;
654            context.arg2 = 4 + imm32;
655            break;
656        default:
657            return false;
658        }
659        data = ReadMemoryUnsigned(context, addr, 4, 0, &success);
660        if (!success)
661            return false;
662        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, data))
663            return false;
664    }
665    return true;
666}
667
668// An add operation to adjust the SP.
669// ADD (SP plus immediate)
670bool
671EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding)
672{
673#if 0
674    // ARM pseudo code...
675    if (ConditionPassed())
676    {
677        EncodingSpecificOperations();
678        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
679        if d == 15 then // Can only occur for ARM encoding
680            ALUWritePC(result); // setflags is always FALSE here
681        else
682            R[d] = result;
683            if setflags then
684                APSR.N = result<31>;
685                APSR.Z = IsZeroBit(result);
686                APSR.C = carry;
687                APSR.V = overflow;
688    }
689#endif
690
691    bool success = false;
692    const uint32_t opcode = OpcodeAsUnsigned (&success);
693    if (!success)
694        return false;
695
696    if (ConditionPassed())
697    {
698        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
699        if (!success)
700            return false;
701        uint32_t imm32; // the immediate operand
702        switch (encoding) {
703        case eEncodingT2:
704            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
705            break;
706        default:
707            return false;
708        }
709        addr_t sp_offset = imm32;
710        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
711
712        EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer,
713                                                eRegisterKindGeneric,
714                                                LLDB_REGNUM_GENERIC_SP,
715                                                sp_offset };
716
717        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
718            return false;
719    }
720    return true;
721}
722
723// An add operation to adjust the SP.
724// ADD (SP plus register)
725bool
726EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding)
727{
728#if 0
729    // ARM pseudo code...
730    if (ConditionPassed())
731    {
732        EncodingSpecificOperations();
733        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
734        (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’);
735        if d == 15 then
736            ALUWritePC(result); // setflags is always FALSE here
737        else
738            R[d] = result;
739            if setflags then
740                APSR.N = result<31>;
741                APSR.Z = IsZeroBit(result);
742                APSR.C = carry;
743                APSR.V = overflow;
744    }
745#endif
746
747    bool success = false;
748    const uint32_t opcode = OpcodeAsUnsigned (&success);
749    if (!success)
750        return false;
751
752    if (ConditionPassed())
753    {
754        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
755        if (!success)
756            return false;
757        uint32_t Rm; // the second operand
758        switch (encoding) {
759        case eEncodingT2:
760            Rm = Bits32(opcode, 6, 3);
761            break;
762        default:
763            return false;
764        }
765        int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
766        if (!success)
767            return false;
768
769        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
770
771        EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer,
772                                                eRegisterKindGeneric,
773                                                LLDB_REGNUM_GENERIC_SP,
774                                                reg_value };
775
776        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
777            return false;
778    }
779    return true;
780}
781
782// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
783// at a PC-relative address, and changes instruction set from ARM to Thumb, or
784// from Thumb to ARM.
785// BLX (immediate)
786bool
787EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding)
788{
789#if 0
790    // ARM pseudo code...
791    if (ConditionPassed())
792    {
793        EncodingSpecificOperations();
794        if CurrentInstrSet() == InstrSet_ARM then
795            LR = PC - 4;
796        else
797            LR = PC<31:1> : '1';
798        if targetInstrSet == InstrSet_ARM then
799            targetAddress = Align(PC,4) + imm32;
800        else
801            targetAddress = PC + imm32;
802        SelectInstrSet(targetInstrSet);
803        BranchWritePC(targetAddress);
804    }
805#endif
806
807    bool success = false;
808    const uint32_t opcode = OpcodeAsUnsigned (&success);
809    if (!success)
810        return false;
811
812    if (ConditionPassed())
813    {
814        EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0};
815        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
816        if (!success)
817            return false;
818        addr_t lr; // next instruction address
819        addr_t target; // target address
820        int32_t imm32; // PC-relative offset
821        switch (encoding) {
822        case eEncodingT1:
823            {
824            lr = (pc + 4) | 1u; // return address
825            uint32_t S = Bit32(opcode, 26);
826            uint32_t imm10 = Bits32(opcode, 25, 16);
827            uint32_t J1 = Bit32(opcode, 13);
828            uint32_t J2 = Bit32(opcode, 11);
829            uint32_t imm11 = Bits32(opcode, 10, 0);
830            uint32_t I1 = !(J1 ^ S);
831            uint32_t I2 = !(J2 ^ S);
832            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
833            imm32 = llvm::SignExtend32<25>(imm25);
834            target = pc + 4 + imm32;
835            context.arg1 = 4 + imm32;  // signed offset
836            context.arg2 = eModeThumb; // target instruction set
837            break;
838            }
839        case eEncodingT2:
840            {
841            lr = (pc + 4) | 1u; // return address
842            uint32_t S = Bit32(opcode, 26);
843            uint32_t imm10H = Bits32(opcode, 25, 16);
844            uint32_t J1 = Bit32(opcode, 13);
845            uint32_t J2 = Bit32(opcode, 11);
846            uint32_t imm10L = Bits32(opcode, 10, 1);
847            uint32_t I1 = !(J1 ^ S);
848            uint32_t I2 = !(J2 ^ S);
849            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
850            imm32 = llvm::SignExtend32<25>(imm25);
851            target = Align(pc + 4, 4) + imm32;
852            context.arg1 = 4 + imm32; // signed offset
853            context.arg2 = eModeARM;  // target instruction set
854            break;
855            }
856        case eEncodingA1:
857            lr = pc + 4; // return address
858            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
859            target = Align(pc + 8, 4) + imm32;
860            context.arg1 = 8 + imm32; // signed offset
861            context.arg2 = eModeARM;  // target instruction set
862            break;
863        case eEncodingA2:
864            lr = pc + 4; // return address
865            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
866            target = pc + 8 + imm32;
867            context.arg1 = 8 + imm32;  // signed offset
868            context.arg2 = eModeThumb; // target instruction set
869            break;
870        default:
871            return false;
872        }
873        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
874            return false;
875        if (!BranchWritePC(context, target))
876            return false;
877    }
878    return true;
879}
880
881// Branch with Link and Exchange (register) calls a subroutine at an address and
882// instruction set specified by a register.
883// BLX (register)
884bool
885EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding)
886{
887#if 0
888    // ARM pseudo code...
889    if (ConditionPassed())
890    {
891        EncodingSpecificOperations();
892        target = R[m];
893        if CurrentInstrSet() == InstrSet_ARM then
894            next_instr_addr = PC - 4;
895            LR = next_instr_addr;
896        else
897            next_instr_addr = PC - 2;
898            LR = next_instr_addr<31:1> : ‘1’;
899        BXWritePC(target);
900    }
901#endif
902
903    bool success = false;
904    const uint32_t opcode = OpcodeAsUnsigned (&success);
905    if (!success)
906        return false;
907
908    if (ConditionPassed())
909    {
910        EmulateInstruction::Context context = { EmulateInstruction::eContextAbsoluteBranchRegister, 0, 0, 0};
911        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
912        addr_t lr; // next instruction address
913        addr_t target; // target address
914        if (!success)
915            return false;
916        uint32_t Rm; // the register with the target address
917        switch (encoding) {
918        case eEncodingT1:
919            lr = (pc + 2) | 1u; // return address
920            Rm = Bits32(opcode, 6, 3);
921            // if m == 15 then UNPREDICTABLE;
922            if (Rm == 15)
923                return false;
924            target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
925            break;
926        case eEncodingA1:
927            lr = pc + 4; // return address
928            Rm = Bits32(opcode, 3, 0);
929            // if m == 15 then UNPREDICTABLE;
930            if (Rm == 15)
931                return false;
932            target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
933            break;
934        default:
935            return false;
936        }
937        context.arg0 = eRegisterKindDWARF;
938        context.arg1 = dwarf_r0 + Rm;
939        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
940            return false;
941        if (!BXWritePC(context, target))
942            return false;
943    }
944    return true;
945}
946
947// Set r7 to point to some ip offset.
948// SUB (immediate)
949bool
950EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding)
951{
952#if 0
953    // ARM pseudo code...
954    if (ConditionPassed())
955    {
956        EncodingSpecificOperations();
957        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
958        if d == 15 then // Can only occur for ARM encoding
959           ALUWritePC(result); // setflags is always FALSE here
960        else
961            R[d] = result;
962            if setflags then
963                APSR.N = result<31>;
964                APSR.Z = IsZeroBit(result);
965                APSR.C = carry;
966                APSR.V = overflow;
967    }
968#endif
969
970    bool success = false;
971    const uint32_t opcode = OpcodeAsUnsigned (&success);
972    if (!success)
973        return false;
974
975    if (ConditionPassed())
976    {
977        const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success);
978        if (!success)
979            return false;
980        uint32_t imm32;
981        switch (encoding) {
982        case eEncodingA1:
983            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
984            break;
985        default:
986            return false;
987        }
988        addr_t ip_offset = imm32;
989        addr_t addr = ip - ip_offset; // the adjusted ip value
990
991        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
992                                                eRegisterKindDWARF,
993                                                dwarf_r12,
994                                                -ip_offset };
995
996        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
997            return false;
998    }
999    return true;
1000}
1001
1002// Set ip to point to some stack offset.
1003// SUB (SP minus immediate)
1004bool
1005EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding)
1006{
1007#if 0
1008    // ARM pseudo code...
1009    if (ConditionPassed())
1010    {
1011        EncodingSpecificOperations();
1012        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
1013        if d == 15 then // Can only occur for ARM encoding
1014           ALUWritePC(result); // setflags is always FALSE here
1015        else
1016            R[d] = result;
1017            if setflags then
1018                APSR.N = result<31>;
1019                APSR.Z = IsZeroBit(result);
1020                APSR.C = carry;
1021                APSR.V = overflow;
1022    }
1023#endif
1024
1025    bool success = false;
1026    const uint32_t opcode = OpcodeAsUnsigned (&success);
1027    if (!success)
1028        return false;
1029
1030    if (ConditionPassed())
1031    {
1032        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1033        if (!success)
1034            return false;
1035        uint32_t imm32;
1036        switch (encoding) {
1037        case eEncodingA1:
1038            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1039            break;
1040        default:
1041            return false;
1042        }
1043        addr_t sp_offset = imm32;
1044        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1045
1046        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
1047                                                eRegisterKindGeneric,
1048                                                LLDB_REGNUM_GENERIC_SP,
1049                                                -sp_offset };
1050
1051        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1052            return false;
1053    }
1054    return true;
1055}
1056
1057// A sub operation to adjust the SP -- allocate space for local storage.
1058bool
1059EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding)
1060{
1061#if 0
1062    // ARM pseudo code...
1063    if (ConditionPassed())
1064    {
1065        EncodingSpecificOperations();
1066        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
1067        if d == 15 then // Can only occur for ARM encoding
1068           ALUWritePC(result); // setflags is always FALSE here
1069        else
1070            R[d] = result;
1071            if setflags then
1072                APSR.N = result<31>;
1073                APSR.Z = IsZeroBit(result);
1074                APSR.C = carry;
1075                APSR.V = overflow;
1076    }
1077#endif
1078
1079    bool success = false;
1080    const uint32_t opcode = OpcodeAsUnsigned (&success);
1081    if (!success)
1082        return false;
1083
1084    if (ConditionPassed())
1085    {
1086        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1087        if (!success)
1088            return false;
1089        uint32_t imm32;
1090        switch (encoding) {
1091        case eEncodingT1:
1092            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1093        case eEncodingT2:
1094            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1095            break;
1096        case eEncodingT3:
1097            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1098            break;
1099        case eEncodingA1:
1100            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1101            break;
1102        default:
1103            return false;
1104        }
1105        addr_t sp_offset = imm32;
1106        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1107
1108        EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer,
1109                                                eRegisterKindGeneric,
1110                                                LLDB_REGNUM_GENERIC_SP,
1111                                                -sp_offset };
1112
1113        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1114            return false;
1115    }
1116    return true;
1117}
1118
1119// A store operation to the stack that also updates the SP.
1120bool
1121EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding)
1122{
1123#if 0
1124    // ARM pseudo code...
1125    if (ConditionPassed())
1126    {
1127        EncodingSpecificOperations();
1128        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1129        address = if index then offset_addr else R[n];
1130        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1131        if wback then R[n] = offset_addr;
1132    }
1133#endif
1134
1135    bool success = false;
1136    const uint32_t opcode = OpcodeAsUnsigned (&success);
1137    if (!success)
1138        return false;
1139
1140    if (ConditionPassed())
1141    {
1142        const uint32_t addr_byte_size = GetAddressByteSize();
1143        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1144        if (!success)
1145            return false;
1146        uint32_t Rt; // the source register
1147        uint32_t imm12;
1148        switch (encoding) {
1149        case eEncodingA1:
1150            Rt = Bits32(opcode, 15, 12);
1151            imm12 = Bits32(opcode, 11, 0);
1152            break;
1153        default:
1154            return false;
1155        }
1156        addr_t sp_offset = imm12;
1157        addr_t addr = sp - sp_offset;
1158
1159        EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 };
1160        if (Rt != 15)
1161        {
1162            context.arg1 = dwarf_r0 + Rt;    // arg1 in the context is the DWARF register number
1163            context.arg2 = addr - sp;        // arg2 in the context is the stack pointer offset
1164            uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success);
1165            if (!success)
1166                return false;
1167            if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size))
1168                return false;
1169        }
1170        else
1171        {
1172            context.arg1 = dwarf_pc;    // arg1 in the context is the DWARF register number
1173            context.arg2 = addr - sp;   // arg2 in the context is the stack pointer offset
1174            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1175            if (!success)
1176                return false;
1177            if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size))
1178                return false;
1179        }
1180
1181        context.type = EmulateInstruction::eContextAdjustStackPointer;
1182        context.arg0 = eRegisterKindGeneric;
1183        context.arg1 = LLDB_REGNUM_GENERIC_SP;
1184        context.arg2 = -sp_offset;
1185
1186        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1187            return false;
1188    }
1189    return true;
1190}
1191
1192// Vector Push stores multiple extension registers to the stack.
1193// It also updates SP to point to the start of the stored data.
1194bool
1195EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding)
1196{
1197#if 0
1198    // ARM pseudo code...
1199    if (ConditionPassed())
1200    {
1201        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1202        address = SP - imm32;
1203        SP = SP - imm32;
1204        if single_regs then
1205            for r = 0 to regs-1
1206                MemA[address,4] = S[d+r]; address = address+4;
1207        else
1208            for r = 0 to regs-1
1209                // Store as two word-aligned words in the correct order for current endianness.
1210                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1211                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1212                address = address+8;
1213    }
1214#endif
1215
1216    bool success = false;
1217    const uint32_t opcode = OpcodeAsUnsigned (&success);
1218    if (!success)
1219        return false;
1220
1221    if (ConditionPassed())
1222    {
1223        const uint32_t addr_byte_size = GetAddressByteSize();
1224        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1225        if (!success)
1226            return false;
1227        bool single_regs;
1228        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1229        uint32_t imm32; // stack offset
1230        uint32_t regs;  // number of registers
1231        switch (encoding) {
1232        case eEncodingT1:
1233        case eEncodingA1:
1234            single_regs = false;
1235            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1236            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1237            // If UInt(imm8) is odd, see "FSTMX".
1238            regs = Bits32(opcode, 7, 0) / 2;
1239            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1240            if (regs == 0 || regs > 16 || (d + regs) > 32)
1241                return false;
1242            break;
1243        case eEncodingT2:
1244        case eEncodingA2:
1245            single_regs = true;
1246            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1247            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1248            regs = Bits32(opcode, 7, 0);
1249            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1250            if (regs == 0 || regs > 16 || (d + regs) > 32)
1251                return false;
1252            break;
1253        default:
1254            return false;
1255        }
1256        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1257        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1258        addr_t sp_offset = imm32;
1259        addr_t addr = sp - sp_offset;
1260        uint32_t i;
1261
1262        EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 };
1263        for (i=d; i<regs; ++i)
1264        {
1265            context.arg1 = start_reg + i;    // arg1 in the context is the DWARF register number
1266            context.arg2 = addr - sp;        // arg2 in the context is the stack pointer offset
1267            // uint64_t to accommodate 64-bit registers.
1268            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success);
1269            if (!success)
1270                return false;
1271            if (!WriteMemoryUnsigned (context, addr, reg_value, reg_byte_size))
1272                return false;
1273            addr += reg_byte_size;
1274        }
1275
1276        context.type = EmulateInstruction::eContextAdjustStackPointer;
1277        context.arg0 = eRegisterKindGeneric;
1278        context.arg1 = LLDB_REGNUM_GENERIC_SP;
1279        context.arg2 = -sp_offset;
1280
1281        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1282            return false;
1283    }
1284    return true;
1285}
1286
1287// Vector Pop loads multiple extension registers from the stack.
1288// It also updates SP to point just above the loaded data.
1289bool
1290EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding)
1291{
1292#if 0
1293    // ARM pseudo code...
1294    if (ConditionPassed())
1295    {
1296        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1297        address = SP;
1298        SP = SP + imm32;
1299        if single_regs then
1300            for r = 0 to regs-1
1301                S[d+r] = MemA[address,4]; address = address+4;
1302        else
1303            for r = 0 to regs-1
1304                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1305                // Combine the word-aligned words in the correct order for current endianness.
1306                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1307    }
1308#endif
1309
1310    bool success = false;
1311    const uint32_t opcode = OpcodeAsUnsigned (&success);
1312    if (!success)
1313        return false;
1314
1315    if (ConditionPassed())
1316    {
1317        const uint32_t addr_byte_size = GetAddressByteSize();
1318        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1319        if (!success)
1320            return false;
1321        bool single_regs;
1322        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1323        uint32_t imm32; // stack offset
1324        uint32_t regs;  // number of registers
1325        switch (encoding) {
1326        case eEncodingT1:
1327        case eEncodingA1:
1328            single_regs = false;
1329            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1330            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1331            // If UInt(imm8) is odd, see "FLDMX".
1332            regs = Bits32(opcode, 7, 0) / 2;
1333            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1334            if (regs == 0 || regs > 16 || (d + regs) > 32)
1335                return false;
1336            break;
1337        case eEncodingT2:
1338        case eEncodingA2:
1339            single_regs = true;
1340            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1341            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1342            regs = Bits32(opcode, 7, 0);
1343            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1344            if (regs == 0 || regs > 16 || (d + regs) > 32)
1345                return false;
1346            break;
1347        default:
1348            return false;
1349        }
1350        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1351        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1352        addr_t sp_offset = imm32;
1353        addr_t addr = sp;
1354        uint32_t i;
1355        uint64_t data; // uint64_t to accomodate 64-bit registers.
1356
1357        EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 };
1358        for (i=d; i<regs; ++i)
1359        {
1360            context.arg1 = start_reg + i;    // arg1 in the context is the DWARF register number
1361            context.arg2 = addr - sp;        // arg2 in the context is the stack pointer offset
1362            data = ReadMemoryUnsigned(context, addr, reg_byte_size, 0, &success);
1363            if (!success)
1364                return false;
1365            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data))
1366                return false;
1367            addr += reg_byte_size;
1368        }
1369
1370        context.type = EmulateInstruction::eContextAdjustStackPointer;
1371        context.arg0 = eRegisterKindGeneric;
1372        context.arg1 = LLDB_REGNUM_GENERIC_SP;
1373        context.arg2 = sp_offset;
1374
1375        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1376            return false;
1377    }
1378    return true;
1379}
1380
1381// SVC (previously SWI)
1382bool
1383EmulateInstructionARM::EmulateSVC (ARMEncoding encoding)
1384{
1385#if 0
1386    // ARM pseudo code...
1387    if (ConditionPassed())
1388    {
1389        EncodingSpecificOperations();
1390        CallSupervisor();
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 uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1402        addr_t lr; // next instruction address
1403        if (!success)
1404            return false;
1405        uint32_t imm32; // the immediate constant
1406        uint32_t mode;  // ARM or Thumb mode
1407        switch (encoding) {
1408        case eEncodingT1:
1409            lr = (pc + 2) | 1u; // return address
1410            imm32 = Bits32(opcode, 7, 0);
1411            mode = eModeThumb;
1412            break;
1413        case eEncodingA1:
1414            lr = pc + 4; // return address
1415            imm32 = Bits32(opcode, 23, 0);
1416            mode = eModeARM;
1417            break;
1418        default:
1419            return false;
1420        }
1421        EmulateInstruction::Context context = { EmulateInstruction::eContextSupervisorCall, mode, imm32, 0};
1422        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1423            return false;
1424    }
1425    return true;
1426}
1427
1428// If Then makes up to four following instructions (the IT block) conditional.
1429bool
1430EmulateInstructionARM::EmulateIT (ARMEncoding encoding)
1431{
1432#if 0
1433    // ARM pseudo code...
1434    EncodingSpecificOperations();
1435    ITSTATE.IT<7:0> = firstcond:mask;
1436#endif
1437
1438    bool success = false;
1439    const uint32_t opcode = OpcodeAsUnsigned (&success);
1440    if (!success)
1441        return false;
1442
1443    m_it_session.InitIT(Bits32(opcode, 7, 0));
1444    return true;
1445}
1446
1447// Branch causes a branch to a target address.
1448bool
1449EmulateInstructionARM::EmulateB (ARMEncoding encoding)
1450{
1451#if 0
1452    // ARM pseudo code...
1453    if (ConditionPassed())
1454    {
1455        EncodingSpecificOperations();
1456        BranchWritePC(PC + imm32);
1457    }
1458#endif
1459
1460    bool success = false;
1461    const uint32_t opcode = OpcodeAsUnsigned (&success);
1462    if (!success)
1463        return false;
1464
1465    if (ConditionPassed())
1466    {
1467        EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0};
1468        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1469        if (!success)
1470            return false;
1471        addr_t target; // target address
1472        int32_t imm32; // PC-relative offset
1473        switch (encoding) {
1474        case eEncodingT1:
1475            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
1476            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
1477            target = pc + 4 + imm32;
1478            context.arg1 = 4 + imm32;  // signed offset
1479            context.arg2 = eModeThumb; // target instruction set
1480            break;
1481        case eEncodingT2:
1482            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
1483            target = pc + 4 + imm32;
1484            context.arg1 = 4 + imm32;  // signed offset
1485            context.arg2 = eModeThumb; // target instruction set
1486            break;
1487        case eEncodingT3:
1488            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
1489            {
1490            uint32_t S = Bit32(opcode, 26);
1491            uint32_t imm6 = Bits32(opcode, 21, 16);
1492            uint32_t J1 = Bit32(opcode, 13);
1493            uint32_t J2 = Bit32(opcode, 11);
1494            uint32_t imm11 = Bits32(opcode, 10, 0);
1495            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
1496            imm32 = llvm::SignExtend32<21>(imm21);
1497            target = pc + 4 + imm32;
1498            context.arg1 = eModeThumb; // target instruction set
1499            context.arg2 = 4 + imm32;  // signed offset
1500            break;
1501            }
1502        case eEncodingT4:
1503            {
1504            uint32_t S = Bit32(opcode, 26);
1505            uint32_t imm10 = Bits32(opcode, 25, 16);
1506            uint32_t J1 = Bit32(opcode, 13);
1507            uint32_t J2 = Bit32(opcode, 11);
1508            uint32_t imm11 = Bits32(opcode, 10, 0);
1509            uint32_t I1 = !(J1 ^ S);
1510            uint32_t I2 = !(J2 ^ S);
1511            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1512            imm32 = llvm::SignExtend32<25>(imm25);
1513            target = pc + 4 + imm32;
1514            context.arg1 = eModeThumb; // target instruction set
1515            context.arg2 = 4 + imm32;  // signed offset
1516            break;
1517            }
1518        case eEncodingA1:
1519            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1520            target = pc + 8 + imm32;
1521            context.arg1 = eModeARM; // target instruction set
1522            context.arg2 = 8 + imm32;  // signed offset
1523            break;
1524        default:
1525            return false;
1526        }
1527        if (!BranchWritePC(context, target))
1528            return false;
1529    }
1530    return true;
1531}
1532
1533// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
1534// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
1535// CBNZ, CBZ
1536bool
1537EmulateInstructionARM::EmulateCB (ARMEncoding encoding)
1538{
1539#if 0
1540    // ARM pseudo code...
1541    EncodingSpecificOperations();
1542    if nonzero ^ IsZero(R[n]) then
1543        BranchWritePC(PC + imm32);
1544#endif
1545
1546    bool success = false;
1547    const uint32_t opcode = OpcodeAsUnsigned (&success);
1548    if (!success)
1549        return false;
1550
1551    // Read the register value from the operand register Rn.
1552    uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success);
1553    if (!success)
1554        return false;
1555
1556    EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0};
1557    const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1558    if (!success)
1559        return false;
1560
1561    addr_t target;  // target address
1562    uint32_t imm32; // PC-relative offset to branch forward
1563    bool nonzero;
1564    switch (encoding) {
1565    case eEncodingT1:
1566        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
1567        nonzero = BitIsSet(opcode, 11);
1568        target = pc + 4 + imm32;
1569        context.arg1 = 4 + imm32;  // signed offset
1570        context.arg2 = eModeThumb; // target instruction set
1571        break;
1572    default:
1573        return false;
1574    }
1575    if (nonzero ^ (reg_val == 0))
1576        if (!BranchWritePC(context, target))
1577            return false;
1578
1579    return true;
1580}
1581
1582// ADD <Rdn>, <Rm>
1583// where <Rdn> the destination register is also the first operand register
1584// and <Rm> is the second operand register.
1585bool
1586EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding)
1587{
1588#if 0
1589    // ARM pseudo code...
1590    if ConditionPassed() then
1591        EncodingSpecificOperations();
1592        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1593        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
1594        if d == 15 then
1595            ALUWritePC(result); // setflags is always FALSE here
1596        else
1597            R[d] = result;
1598            if setflags then
1599                APSR.N = result<31>;
1600                APSR.Z = IsZeroBit(result);
1601                APSR.C = carry;
1602                APSR.V = overflow;
1603#endif
1604
1605    bool success = false;
1606    const uint32_t opcode = OpcodeAsUnsigned (&success);
1607    if (!success)
1608        return false;
1609
1610    if (ConditionPassed())
1611    {
1612        uint32_t Rd, Rn, Rm;
1613        //bool setflags = false;
1614        switch (encoding)
1615        {
1616        case eEncodingT2:
1617            // setflags = FALSE
1618            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
1619            Rm = Bits32(opcode, 6, 3);
1620            if (Rn == 15 && Rm == 15)
1621                return false;
1622            break;
1623        default:
1624            return false;
1625        }
1626
1627        int32_t result, val1, val2;
1628        // Read the first operand.
1629        if (Rn == 15)
1630            val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1631        else
1632            val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
1633        if (!success)
1634            return false;
1635
1636        // Read the second operand.
1637        if (Rm == 15)
1638            val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1639        else
1640            val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1641        if (!success)
1642            return false;
1643
1644        result = val1 + val2;
1645        EmulateInstruction::Context context = { EmulateInstruction::eContextImmediate,
1646                                                result,
1647                                                0,
1648                                                0 };
1649
1650        if (Rd == 15)
1651        {
1652            if (!ALUWritePC (context, result))
1653                return false;
1654        }
1655        else
1656        {
1657            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, result))
1658                return false;
1659        }
1660    }
1661    return true;
1662}
1663
1664bool
1665EmulateInstructionARM::EmulateCmpRnImm (ARMEncoding encoding)
1666{
1667#if 0
1668    // ARM pseudo code...
1669    if ConditionPassed() then
1670        EncodingSpecificOperations();
1671        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
1672        APSR.N = result<31>;
1673        APSR.Z = IsZeroBit(result);
1674        APSR.C = carry;
1675        APSR.V = overflow;
1676#endif
1677
1678    bool success = false;
1679    const uint32_t opcode = OpcodeAsUnsigned (&success);
1680    if (!success)
1681        return false;
1682
1683    uint32_t Rn; // the first operand
1684    uint32_t imm32; // the immediate value to be compared with
1685    switch (encoding) {
1686    case eEncodingT1:
1687        Rn = Bits32(opcode, 10, 8);
1688        imm32 = Bits32(opcode, 7, 0);
1689        break;
1690    default:
1691        return false;
1692    }
1693    // Read the register value from the operand register Rn.
1694    uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
1695    if (!success)
1696        return false;
1697
1698    EmulateInstruction::Context context = { EmulateInstruction::eContextImmediate, 0, 0, 0};
1699    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
1700    m_new_inst_cpsr = m_inst_cpsr;
1701    SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(res.result, CPSR_N));
1702    SetBit32(m_new_inst_cpsr, CPSR_Z, res.result == 0 ? 1 : 0);
1703    SetBit32(m_new_inst_cpsr, CPSR_C, res.carry_out);
1704    SetBit32(m_new_inst_cpsr, CPSR_V, res.overflow);
1705    if (m_new_inst_cpsr != m_inst_cpsr)
1706    {
1707        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1708            return false;
1709    }
1710    return true;
1711}
1712
1713// LDM loads multiple registers from consecutive memory locations, using an
1714// address from a base register.  Optionally the addres just above the highest of those locations
1715// can be written back to the base register.
1716bool
1717EmulateInstructionARM::EmulateLDM (ARMEncoding encoding)
1718{
1719#if 0
1720    // ARM pseudo code...
1721    if ConditionPassed()
1722        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
1723        address = R[n];
1724
1725        for i = 0 to 14
1726            if registers<i> == '1' then
1727                R[i] = MemA[address, 4]; address = address + 4;
1728        if registers<15> == '1' then
1729            LoadWritePC (MemA[address, 4]);
1730
1731        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
1732        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
1733
1734#endif
1735
1736    bool success = false;
1737    const uint32_t opcode = OpcodeAsUnsigned (&success);
1738    if (!success)
1739        return false;
1740
1741    if (ConditionPassed())
1742    {
1743        uint32_t n;
1744        uint32_t registers = 0;
1745        bool wback;
1746        const uint32_t addr_byte_size = GetAddressByteSize();
1747        switch (encoding)
1748        {
1749            case eEncodingT1:
1750                n = Bits32 (opcode, 10, 8);
1751                registers = Bits32 (opcode, 7, 0);
1752                wback = BitIsClear (registers, n);
1753                // if BitCount(registers) < 1 then UNPREDICTABLE;
1754                if (BitCount(registers) < 1)
1755                    return false;
1756                break;
1757            case eEncodingT2:
1758                n = Bits32 (opcode, 19, 16);
1759                registers = Bits32 (opcode, 15, 0);
1760                wback = BitIsSet (opcode, 21);
1761                if ((n == 15)
1762                    || (BitCount (registers) < 2)
1763                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
1764                    return false;
1765                if (BitIsSet (registers, 15)
1766                    && m_it_session.InITBlock()
1767                    && !m_it_session.LastInITBlock())
1768                    return false;
1769                if (wback
1770                    && BitIsSet (registers, n))
1771                    return false;
1772                break;
1773            case eEncodingA1:
1774                n = Bits32 (opcode, 19, 16);
1775                registers = Bits32 (opcode, 15, 0);
1776                wback = BitIsSet (opcode, 21);
1777                if ((n == 15)
1778                    || (BitCount (registers) < 1))
1779                    return false;
1780                break;
1781            default:
1782                return false;
1783        }
1784
1785        int32_t offset = 0;
1786        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1787        if (!success)
1788            return false;
1789
1790        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
1791                                                eRegisterKindDWARF,
1792                                                dwarf_r0 + n,
1793                                                offset };
1794
1795        for (int i = 0; i < 14; ++i)
1796        {
1797            if (BitIsSet (registers, i))
1798            {
1799                context.type = EmulateInstruction::eContextRegisterPlusOffset;
1800                context.arg2 = offset;
1801                if (wback && (n == 13)) // Pop Instruction
1802                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
1803
1804                // R[i] = MemA [address, 4]; address = address + 4;
1805                uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success);
1806                if (!success)
1807                    return false;
1808
1809                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
1810                    return false;
1811
1812                offset += addr_byte_size;
1813            }
1814        }
1815
1816        if (BitIsSet (registers, 15))
1817        {
1818            //LoadWritePC (MemA [address, 4]);
1819            context.type = EmulateInstruction::eContextRegisterPlusOffset;
1820            context.arg2 = offset;
1821            uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success);
1822            if (!success)
1823                return false;
1824            // In ARMv5T and above, this is an interworking branch.
1825            if (!LoadWritePC(context, data))
1826                return false;
1827        }
1828
1829        if (wback && BitIsClear (registers, n))
1830        {
1831            addr_t offset = addr_byte_size * BitCount (registers);
1832            context.type = EmulateInstruction::eContextRegisterPlusOffset;
1833            context.arg2 = offset;
1834
1835            // R[n] = R[n] + 4 * BitCount (registers)
1836            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
1837                return false;
1838        }
1839        if (wback && BitIsSet (registers, n))
1840            // R[n] bits(32) UNKNOWN;
1841            return false; //I'm not convinced this is the right thing to do here...
1842    }
1843    return true;
1844}
1845
1846bool
1847EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding)
1848{
1849#if 0
1850    // ARM pseudo code...
1851    if ConditionPassed() then
1852        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
1853        address = R[n] - 4*BitCount(registers);
1854
1855        for i = 0 to 14
1856            if registers<i> == ’1then
1857                  R[i] = MemA[address,4]; address = address + 4;
1858        if registers<15> == ’1then
1859                  LoadWritePC(MemA[address,4]);
1860
1861        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
1862        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
1863#endif
1864
1865    bool success = false;
1866    const uint32_t opcode = OpcodeAsUnsigned (&success);
1867    if (!success)
1868        return false;
1869
1870    if (ConditionPassed())
1871    {
1872        uint32_t n;
1873        uint32_t registers = 0;
1874        bool wback;
1875        const uint32_t addr_byte_size = GetAddressByteSize();
1876        switch (encoding)
1877        {
1878            case eEncodingT1:
1879                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
1880                n = Bits32 (opcode, 19, 16);
1881                registers = Bits32 (opcode, 15, 0);
1882                wback = BitIsSet (opcode, 21);
1883
1884                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
1885                if ((n == 15)
1886                    || (BitCount (registers) < 2)
1887                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
1888                    return false;
1889
1890                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
1891                if (BitIsSet (registers, 15)
1892                    && m_it_session.InITBlock()
1893                    && !m_it_session.LastInITBlock())
1894                    return false;
1895
1896                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
1897                if (wback && BitIsSet (registers, n))
1898                    return false;
1899
1900                break;
1901
1902            case eEncodingA1:
1903                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
1904                n = Bits32 (opcode, 19, 16);
1905                registers = Bits32 (opcode, 15, 0);
1906                wback = BitIsSet (opcode, 21);
1907
1908                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
1909                if ((n == 15) || (BitCount (registers) < 1))
1910                    return false;
1911
1912                break;
1913
1914            default:
1915                return false;
1916        }
1917
1918        int32_t offset = 0;
1919        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success)
1920                                                                             - (addr_byte_size * BitCount (registers));
1921        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
1922                                                eRegisterKindDWARF,
1923                                                dwarf_r0 + n,
1924                                                offset };
1925
1926        for (int i = 0; i < 14; ++i)
1927        {
1928            if (BitIsSet (registers, i))
1929            {
1930                // R[i] = MemA[address,4]; address = address + 4;
1931                context.arg2 = offset;
1932                uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success);
1933                if (!success)
1934                    return false;
1935
1936                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
1937                    return false;
1938
1939                offset += addr_byte_size;
1940            }
1941        }
1942
1943        // if registers<15> == ’1’ then
1944        //     LoadWritePC(MemA[address,4]);
1945        if (BitIsSet (registers, 15))
1946        {
1947            context.arg2 = offset;
1948            uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success);
1949            if (!success)
1950                return false;
1951            // In ARMv5T and above, this is an interworking branch.
1952            if (!LoadWritePC(context, data))
1953                return false;
1954        }
1955
1956        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
1957        if (wback && BitIsClear (registers, n))
1958        {
1959            context.arg2 = offset;
1960            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1961            if (!success)
1962                return false;
1963            addr = addr - (addr_byte_size * BitCount (registers));
1964            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
1965                return false;
1966        }
1967
1968        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
1969        if (wback && BitIsSet (registers, n))
1970            return false;  // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN.
1971    }
1972    return true;
1973}
1974
1975bool
1976EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding)
1977{
1978#if 0
1979    if ConditionPassed() then
1980        EncodingSpecificOperations();
1981        address = R[n] + 4;
1982
1983        for i = 0 to 14
1984            if registers<i> == ’1then
1985                  R[i] = MemA[address,4]; address = address + 4;
1986        if registers<15> == ’1then
1987            LoadWritePC(MemA[address,4]);
1988
1989        if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
1990        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
1991#endif
1992
1993    bool success = false;
1994    const uint32_t opcode = OpcodeAsUnsigned (&success);
1995    if (!success)
1996        return false;
1997
1998    if (ConditionPassed())
1999    {
2000        uint32_t n;
2001        uint32_t registers = 0;
2002        bool wback;
2003        const uint32_t addr_byte_size = GetAddressByteSize();
2004        switch (encoding)
2005        {
2006            case eEncodingA1:
2007                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
2008                n = Bits32 (opcode, 19, 16);
2009                registers = Bits32 (opcode, 15, 0);
2010                wback = BitIsSet (opcode, 21);
2011
2012                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
2013                if ((n == 15) || (BitCount (registers) < 1))
2014                    return false;
2015
2016                break;
2017            default:
2018                return false;
2019        }
2020        // address = R[n] + 4;
2021
2022        int32_t offset = 0;
2023        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) + addr_byte_size;
2024
2025        EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset,
2026                                                eRegisterKindDWARF,
2027                                                dwarf_r0 + n,
2028                                                offset };
2029
2030        for (int i = 0; i < 14; ++i)
2031        {
2032            if (BitIsSet (registers, i))
2033            {
2034                // R[i] = MemA[address,4]; address = address + 4;
2035
2036                context.arg2 = offset;
2037                uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success);
2038                if (!success)
2039                    return false;
2040
2041                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2042                    return false;
2043
2044                offset += addr_byte_size;
2045            }
2046        }
2047
2048        // if registers<15> == ’1’ then
2049        //     LoadWritePC(MemA[address,4]);
2050        if (BitIsSet (registers, 15))
2051        {
2052            context.arg2 = offset;
2053            uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success);
2054            if (!success)
2055                return false;
2056            // In ARMv5T and above, this is an interworking branch.
2057            if (!LoadWritePC(context, data))
2058                return false;
2059        }
2060
2061        // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
2062        if (wback && BitIsClear (registers, n))
2063        {
2064            context.arg2 = offset;
2065            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2066            if (!success)
2067                return false;
2068            addr = addr + (addr_byte_size * BitCount (registers));
2069            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
2070                return false;
2071        }
2072
2073        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
2074        if (wback && BitIsSet (registers, n))
2075            return false;  // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN.
2076    }
2077    return true;
2078}
2079
2080// Load Register (immediate) calculates an address from a base register value and
2081// an immediate offset, loads a word from memory, and writes to a register.
2082// LDR (immediate, Thumb)
2083bool
2084EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
2085{
2086#if 0
2087    // ARM pseudo code...
2088    if (ConditionPassed())
2089    {
2090        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
2091        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
2092        address = if index then offset_addr else R[n];
2093        data = MemU[address,4];
2094        if wback then R[n] = offset_addr;
2095        if t == 15 then
2096            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
2097        elsif UnalignedSupport() || address<1:0> = '00' then
2098            R[t] = data;
2099        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
2100    }
2101#endif
2102
2103    bool success = false;
2104    const uint32_t opcode = OpcodeAsUnsigned (&success);
2105    if (!success)
2106        return false;
2107
2108    if (ConditionPassed())
2109    {
2110        uint32_t Rt; // the destination register
2111        uint32_t Rn; // the base register
2112        uint32_t imm32; // the immediate offset used to form the address
2113        addr_t offset_addr; // the offset address
2114        addr_t address; // the calculated address
2115        uint32_t data; // the literal data value from memory load
2116        bool add, index, wback;
2117        switch (encoding) {
2118        case eEncodingT1:
2119            Rt = Bits32(opcode, 5, 3);
2120            Rn = Bits32(opcode, 2, 0);
2121            imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
2122            // index = TRUE; add = TRUE; wback = FALSE
2123            add = true;
2124            index = true;
2125            wback = false;
2126            break;
2127        default:
2128            return false;
2129        }
2130        uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2131        if (!success)
2132            return false;
2133        if (add)
2134            offset_addr = base + imm32;
2135        else
2136            offset_addr = base - imm32;
2137
2138        address = (index ? offset_addr : base);
2139
2140        if (wback)
2141        {
2142            EmulateInstruction::Context ctx = { EmulateInstruction::eContextRegisterPlusOffset,
2143                                                eRegisterKindDWARF,
2144                                                dwarf_r0 + Rn,
2145                                                (int32_t) (offset_addr - base)};
2146            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
2147                return false;
2148        }
2149
2150        // Prepare to write to the Rt register.
2151        EmulateInstruction::Context context = {EmulateInstruction::eContextImmediate,
2152                                               0,
2153                                               0,
2154                                               0};
2155
2156        // Read memory from the address.
2157        data = ReadMemoryUnsigned(context, address, 4, 0, &success);
2158        if (!success)
2159            return false;
2160        context.arg0 = data;
2161
2162        if (Rt == 15)
2163        {
2164            if (Bits32(address, 1, 0) == 0)
2165            {
2166                if (!LoadWritePC(context, data))
2167                    return false;
2168            }
2169            else
2170                return false;
2171        }
2172        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
2173        {
2174            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
2175                return false;
2176        }
2177        else
2178            return false;
2179    }
2180    return true;
2181}
2182
2183EmulateInstructionARM::ARMOpcode*
2184EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
2185{
2186    static ARMOpcode
2187    g_arm_opcodes[] =
2188    {
2189        //----------------------------------------------------------------------
2190        // Prologue instructions
2191        //----------------------------------------------------------------------
2192
2193        // push register(s)
2194        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" },
2195        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" },
2196
2197        // set r7 to point to a stack offset
2198        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" },
2199        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"},
2200        // copy the stack pointer to ip
2201        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" },
2202        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" },
2203        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"},
2204
2205        // adjust the stack pointer
2206        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"},
2207
2208        // push one register
2209        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
2210        { 0x0fff0000, 0x052d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
2211
2212        // vector push consecutive extension register(s)
2213        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
2214        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
2215
2216        //----------------------------------------------------------------------
2217        // Epilogue instructions
2218        //----------------------------------------------------------------------
2219
2220        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
2221        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
2222        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
2223        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
2224        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"},
2225        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"},
2226        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
2227        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
2228
2229        //----------------------------------------------------------------------
2230        // Supervisor Call (previously Software Interrupt)
2231        //----------------------------------------------------------------------
2232        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
2233
2234        //----------------------------------------------------------------------
2235        // Branch instructions
2236        //----------------------------------------------------------------------
2237        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"},
2238
2239        //----------------------------------------------------------------------
2240        // Load instructions
2241        //----------------------------------------------------------------------
2242        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
2243        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
2244        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }
2245
2246    };
2247    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
2248
2249    for (size_t i=0; i<k_num_arm_opcodes; ++i)
2250    {
2251        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
2252            return &g_arm_opcodes[i];
2253    }
2254    return NULL;
2255}
2256
2257
2258EmulateInstructionARM::ARMOpcode*
2259EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
2260{
2261
2262    static ARMOpcode
2263    g_thumb_opcodes[] =
2264    {
2265        //----------------------------------------------------------------------
2266        // Prologue instructions
2267        //----------------------------------------------------------------------
2268
2269        // push register(s)
2270        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" },
2271        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" },
2272        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" },
2273
2274        // set r7 to point to a stack offset
2275        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" },
2276        // copy the stack pointer to r7
2277        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" },
2278        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
2279        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" },
2280
2281        // PC relative load into register (see also EmulateAddSPRm)
2282        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRdPCRelative, "ldr <Rd>, [PC, #imm]"},
2283
2284        // adjust the stack pointer
2285        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"},
2286        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"},
2287        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"},
2288        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"},
2289
2290        // vector push consecutive extension register(s)
2291        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
2292        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
2293
2294        //----------------------------------------------------------------------
2295        // Epilogue instructions
2296        //----------------------------------------------------------------------
2297
2298        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"},
2299        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
2300        // J1 == J2 == 1
2301        { 0xf800f800, 0xf000f800, ARMV4T_ABOVE,  eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
2302        // J1 == J2 == 1
2303        { 0xf800e800, 0xf000e800, ARMV5_ABOVE,   eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
2304        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"},
2305        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" },
2306        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" },
2307        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
2308        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
2309
2310        //----------------------------------------------------------------------
2311        // Supervisor Call (previously Software Interrupt)
2312        //----------------------------------------------------------------------
2313        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
2314
2315        //----------------------------------------------------------------------
2316        // If Then makes up to four following instructions conditional.
2317        //----------------------------------------------------------------------
2318        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
2319
2320        //----------------------------------------------------------------------
2321        // Branch instructions
2322        //----------------------------------------------------------------------
2323        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
2324        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
2325        { 0xffff8000, 0x0000e000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"},
2326        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
2327        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"},
2328        // compare and branch
2329        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
2330
2331        //----------------------------------------------------------------------
2332        // Data-processing instructions
2333        //----------------------------------------------------------------------
2334        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
2335        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdnRm, "add <Rdn>, <Rm>"},
2336        // move from high register to high register
2337        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "mov<c> <Rd>, <Rm>"},
2338        // move from low register to low register
2339        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "movs <Rd>, <Rm>"},
2340        // compare a register with immediate
2341        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCmpRnImm, "cmp<c> <Rn>, #imm8"},
2342
2343        //----------------------------------------------------------------------
2344        // Load instructions
2345        //----------------------------------------------------------------------
2346        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
2347        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
2348        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
2349        { 0xfffff800, 0x00006800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}
2350
2351    };
2352
2353    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
2354    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
2355    {
2356        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
2357            return &g_thumb_opcodes[i];
2358    }
2359    return NULL;
2360}
2361
2362bool
2363EmulateInstructionARM::SetTargetTriple (const ConstString &triple)
2364{
2365    m_arm_isa = 0;
2366    const char *triple_cstr = triple.GetCString();
2367    if (triple_cstr)
2368    {
2369        const char *dash = ::strchr (triple_cstr, '-');
2370        if (dash)
2371        {
2372            std::string arch (triple_cstr, dash);
2373            const char *arch_cstr = arch.c_str();
2374            if (strcasecmp(arch_cstr, "armv4t") == 0)
2375                m_arm_isa = ARMv4T;
2376            else if (strcasecmp(arch_cstr, "armv4") == 0)
2377                m_arm_isa = ARMv4;
2378            else if (strcasecmp(arch_cstr, "armv5tej") == 0)
2379                m_arm_isa = ARMv5TEJ;
2380            else if (strcasecmp(arch_cstr, "armv5te") == 0)
2381                m_arm_isa = ARMv5TE;
2382            else if (strcasecmp(arch_cstr, "armv5t") == 0)
2383                m_arm_isa = ARMv5T;
2384            else if (strcasecmp(arch_cstr, "armv6k") == 0)
2385                m_arm_isa = ARMv6K;
2386            else if (strcasecmp(arch_cstr, "armv6") == 0)
2387                m_arm_isa = ARMv6;
2388            else if (strcasecmp(arch_cstr, "armv6t2") == 0)
2389                m_arm_isa = ARMv6T2;
2390            else if (strcasecmp(arch_cstr, "armv7") == 0)
2391                m_arm_isa = ARMv7;
2392            else if (strcasecmp(arch_cstr, "armv8") == 0)
2393                m_arm_isa = ARMv8;
2394        }
2395    }
2396    return m_arm_isa != 0;
2397}
2398
2399
2400bool
2401EmulateInstructionARM::ReadInstruction ()
2402{
2403    bool success = false;
2404    m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
2405    if (success)
2406    {
2407        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
2408        if (success)
2409        {
2410            Context read_inst_context = {eContextReadOpcode, 0, 0};
2411            if (m_inst_cpsr & MASK_CPSR_T)
2412            {
2413                m_inst_mode = eModeThumb;
2414                uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success);
2415
2416                if (success)
2417                {
2418                    if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0))
2419                    {
2420                        m_inst.opcode_type = eOpcode16;
2421                        m_inst.opcode.inst16 = thumb_opcode;
2422                    }
2423                    else
2424                    {
2425                        m_inst.opcode_type = eOpcode32;
2426                        m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success);
2427                    }
2428                }
2429            }
2430            else
2431            {
2432                m_inst_mode = eModeARM;
2433                m_inst.opcode_type = eOpcode32;
2434                m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success);
2435            }
2436        }
2437    }
2438    if (!success)
2439    {
2440        m_inst_mode = eModeInvalid;
2441        m_inst_pc = LLDB_INVALID_ADDRESS;
2442    }
2443    return success;
2444}
2445
2446uint32_t
2447EmulateInstructionARM::ArchVersion ()
2448{
2449    return m_arm_isa;
2450}
2451
2452bool
2453EmulateInstructionARM::ConditionPassed ()
2454{
2455    if (m_inst_cpsr == 0)
2456        return false;
2457
2458    const uint32_t cond = CurrentCond ();
2459
2460    if (cond == UINT32_MAX)
2461        return false;
2462
2463    bool result = false;
2464    switch (UnsignedBits(cond, 3, 1))
2465    {
2466    case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break;
2467    case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break;
2468    case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break;
2469    case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break;
2470    case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break;
2471    case 5:
2472        {
2473            bool n = (m_inst_cpsr & MASK_CPSR_N);
2474            bool v = (m_inst_cpsr & MASK_CPSR_V);
2475            result = n == v;
2476        }
2477        break;
2478    case 6:
2479        {
2480            bool n = (m_inst_cpsr & MASK_CPSR_N);
2481            bool v = (m_inst_cpsr & MASK_CPSR_V);
2482            result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0);
2483        }
2484        break;
2485    case 7:
2486        result = true;
2487        break;
2488    }
2489
2490    if (cond & 1)
2491        result = !result;
2492    return result;
2493}
2494
2495uint32_t
2496EmulateInstructionARM::CurrentCond ()
2497{
2498    switch (m_inst_mode)
2499    {
2500    default:
2501    case eModeInvalid:
2502        break;
2503
2504    case eModeARM:
2505        return UnsignedBits(m_inst.opcode.inst32, 31, 28);
2506
2507    case eModeThumb:
2508        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
2509        // 'cond' field of the encoding.
2510        if (m_inst.opcode_type == eOpcode16 &&
2511            Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d &&
2512            Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f)
2513        {
2514            return Bits32(m_inst.opcode.inst16, 11, 7);
2515        }
2516        else if (m_inst.opcode_type == eOpcode32 &&
2517                 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e &&
2518                 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 &&
2519                 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 &&
2520                 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d)
2521        {
2522            return Bits32(m_inst.opcode.inst32, 25, 22);
2523        }
2524
2525        return m_it_session.GetCond();
2526    }
2527    return UINT32_MAX;  // Return invalid value
2528}
2529
2530bool
2531EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
2532{
2533    addr_t target;
2534
2535    // Check the current instruction set.
2536    if (CurrentInstrSet() == eModeARM)
2537        target = addr & 0xfffffffc;
2538    else
2539        target = addr & 0xfffffffe;
2540
2541    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
2542        return false;
2543
2544    return true;
2545}
2546
2547// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
2548bool
2549EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
2550{
2551    addr_t target;
2552    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
2553    // we want to record it and issue a WriteRegister callback so the clients
2554    // can track the mode changes accordingly.
2555    bool cpsr_changed = false;
2556
2557    if (BitIsSet(addr, 0))
2558    {
2559        if (CurrentInstrSet() != eModeThumb)
2560        {
2561            SelectInstrSet(eModeThumb);
2562            cpsr_changed = true;
2563        }
2564        target = addr & 0xfffffffe;
2565        context.arg2 = eModeThumb;
2566    }
2567    else if (BitIsClear(addr, 1))
2568    {
2569        if (CurrentInstrSet() != eModeARM)
2570        {
2571            SelectInstrSet(eModeARM);
2572            cpsr_changed = true;
2573        }
2574        target = addr & 0xfffffffc;
2575        context.arg2 = eModeARM;
2576    }
2577    else
2578        return false; // address<1:0> == '10' => UNPREDICTABLE
2579
2580    if (cpsr_changed)
2581    {
2582        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
2583            return false;
2584    }
2585    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
2586        return false;
2587
2588    return true;
2589}
2590
2591// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
2592bool
2593EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
2594{
2595    if (ArchVersion() >= ARMv5T)
2596        return BXWritePC(context, addr);
2597    else
2598        return BranchWritePC((const Context)context, addr);
2599}
2600
2601// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
2602bool
2603EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
2604{
2605    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
2606        return BXWritePC(context, addr);
2607    else
2608        return BranchWritePC((const Context)context, addr);
2609}
2610
2611EmulateInstructionARM::Mode
2612EmulateInstructionARM::CurrentInstrSet ()
2613{
2614    return m_inst_mode;
2615}
2616
2617// Set the 'T' bit of our CPSR.  The m_inst_mode gets updated when the next
2618// ReadInstruction() is performed.  This function has a side effect of updating
2619// the m_new_inst_cpsr member variable if necessary.
2620bool
2621EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
2622{
2623    m_new_inst_cpsr = m_inst_cpsr;
2624    switch (arm_or_thumb)
2625    {
2626    default:
2627        return false;
2628    eModeARM:
2629        // Clear the T bit.
2630        m_new_inst_cpsr &= ~MASK_CPSR_T;
2631        break;
2632    eModeThumb:
2633        // Set the T bit.
2634        m_new_inst_cpsr |= MASK_CPSR_T;
2635        break;
2636    }
2637    return true;
2638}
2639
2640// This function returns TRUE if the processor currently provides support for
2641// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
2642// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
2643bool
2644EmulateInstructionARM::UnalignedSupport()
2645{
2646    return (ArchVersion() >= ARMv7);
2647}
2648
2649// The main addition and subtraction instructions can produce status information
2650// about both unsigned carry and signed overflow conditions.  This status
2651// information can be used to synthesize multi-word additions and subtractions.
2652EmulateInstructionARM::AddWithCarryResult
2653EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
2654{
2655    uint32_t result;
2656    uint8_t carry_out;
2657    uint8_t overflow;
2658
2659    uint64_t unsigned_sum = x + y + carry_in;
2660    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
2661
2662    result = UnsignedBits(unsigned_sum, 31, 0);
2663    carry_out = (result == unsigned_sum ? 0 : 1);
2664    overflow = ((int32_t)result == signed_sum ? 0 : 1);
2665
2666    AddWithCarryResult res = { result, carry_out, overflow };
2667    return res;
2668}
2669
2670bool
2671EmulateInstructionARM::EvaluateInstruction ()
2672{
2673    // Advance the ITSTATE bits to their values for the next instruction.
2674    if (m_inst_mode == eModeThumb && m_it_session.InITBlock())
2675        m_it_session.ITAdvance();
2676
2677    return false;
2678}
2679