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