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