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