EmulateInstructionARM.cpp revision 1f954f59df9ce7bf58d0353ab0949656561210d4
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/Address.h"
15#include "lldb/Core/ConstString.h"
16#include "lldb/Core/PluginManager.h"
17
18#include "Plugins/Process/Utility/ARMDefines.h"
19#include "Plugins/Process/Utility/ARMUtils.h"
20#include "Utility/ARM_DWARF_Registers.h"
21
22#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
23                                     // and CountTrailingZeros_32 function
24
25using namespace lldb;
26using namespace lldb_private;
27
28// Convenient macro definitions.
29#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
30#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
31
32#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
33
34//----------------------------------------------------------------------
35//
36// ITSession implementation
37//
38//----------------------------------------------------------------------
39
40// A8.6.50
41// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
42static unsigned short CountITSize(unsigned ITMask) {
43    // First count the trailing zeros of the IT mask.
44    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
45    if (TZ > 3)
46    {
47        printf("Encoding error: IT Mask '0000'\n");
48        return 0;
49    }
50    return (4 - TZ);
51}
52
53// Init ITState.  Note that at least one bit is always 1 in mask.
54bool ITSession::InitIT(unsigned short bits7_0)
55{
56    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
57    if (ITCounter == 0)
58        return false;
59
60    // A8.6.50 IT
61    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
62    if (FirstCond == 0xF)
63    {
64        printf("Encoding error: IT FirstCond '1111'\n");
65        return false;
66    }
67    if (FirstCond == 0xE && ITCounter != 1)
68    {
69        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
70        return false;
71    }
72
73    ITState = bits7_0;
74    return true;
75}
76
77// Update ITState if necessary.
78void ITSession::ITAdvance()
79{
80    assert(ITCounter);
81    --ITCounter;
82    if (ITCounter == 0)
83        ITState = 0;
84    else
85    {
86        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
87        SetBits32(ITState, 4, 0, NewITState4_0);
88    }
89}
90
91// Return true if we're inside an IT Block.
92bool ITSession::InITBlock()
93{
94    return ITCounter != 0;
95}
96
97// Return true if we're the last instruction inside an IT Block.
98bool ITSession::LastInITBlock()
99{
100    return ITCounter == 1;
101}
102
103// Get condition bits for the current thumb instruction.
104uint32_t ITSession::GetCond()
105{
106    if (InITBlock())
107        return Bits32(ITState, 7, 4);
108    else
109        return COND_AL;
110}
111
112// ARM constants used during decoding
113#define REG_RD          0
114#define LDM_REGLIST     1
115#define SP_REG          13
116#define LR_REG          14
117#define PC_REG          15
118#define PC_REGLIST_BIT  0x8000
119
120#define ARMv4     (1u << 0)
121#define ARMv4T    (1u << 1)
122#define ARMv5T    (1u << 2)
123#define ARMv5TE   (1u << 3)
124#define ARMv5TEJ  (1u << 4)
125#define ARMv6     (1u << 5)
126#define ARMv6K    (1u << 6)
127#define ARMv6T2   (1u << 7)
128#define ARMv7     (1u << 8)
129#define ARMv8     (1u << 9)
130#define ARMvAll   (0xffffffffu)
131
132#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
133#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
134#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
135#define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
136#define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
137#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
138
139#define No_VFP  0
140#define VFPv1   (1u << 1)
141#define VFPv2   (1u << 2)
142#define VFPv3   (1u << 3)
143#define AdvancedSIMD (1u << 4)
144
145#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
146#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
147#define VFPv2v3     (VFPv2 | VFPv3)
148
149//----------------------------------------------------------------------
150//
151// EmulateInstructionARM implementation
152//
153//----------------------------------------------------------------------
154
155void
156EmulateInstructionARM::Initialize ()
157{
158    PluginManager::RegisterPlugin (GetPluginNameStatic (),
159                                   GetPluginDescriptionStatic (),
160                                   CreateInstance);
161}
162
163void
164EmulateInstructionARM::Terminate ()
165{
166    PluginManager::UnregisterPlugin (CreateInstance);
167}
168
169const char *
170EmulateInstructionARM::GetPluginNameStatic ()
171{
172    return "lldb.emulate-instruction.arm";
173}
174
175const char *
176EmulateInstructionARM::GetPluginDescriptionStatic ()
177{
178    return "Emulate instructions for the ARM architecture.";
179}
180
181EmulateInstruction *
182EmulateInstructionARM::CreateInstance (const ArchSpec &arch)
183{
184    if (arch.GetTriple().getArch() == llvm::Triple::arm)
185    {
186        std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
187
188        if (emulate_insn_ap.get())
189            return emulate_insn_ap.release();
190    }
191    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
192    {
193        std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
194
195        if (emulate_insn_ap.get())
196            return emulate_insn_ap.release();
197    }
198
199    return NULL;
200}
201
202bool
203EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
204{
205    if (arch.GetTriple().getArch () == llvm::Triple::arm)
206        return true;
207    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
208        return true;
209
210    return false;
211}
212
213// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
214bool
215EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
216{
217    EmulateInstruction::Context context;
218    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
219    context.SetNoArgs ();
220
221    uint32_t random_data = rand ();
222    const uint32_t addr_byte_size = GetAddressByteSize();
223
224    if (!MemAWrite (context, address, random_data, addr_byte_size))
225        return false;
226
227    return true;
228}
229
230// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
231bool
232EmulateInstructionARM::WriteBits32Unknown (int n)
233{
234    EmulateInstruction::Context context;
235    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
236    context.SetNoArgs ();
237
238    bool success;
239    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
240
241    if (!success)
242        return false;
243
244    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
245        return false;
246
247    return true;
248}
249
250// Push Multiple Registers stores multiple registers to the stack, storing to
251// consecutive memory locations ending just below the address in SP, and updates
252// SP to point to the start of the stored data.
253bool
254EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
255{
256#if 0
257    // ARM pseudo code...
258    if (ConditionPassed())
259    {
260        EncodingSpecificOperations();
261        NullCheckIfThumbEE(13);
262        address = SP - 4*BitCount(registers);
263
264        for (i = 0 to 14)
265        {
266            if (registers<i> == '1')
267            {
268                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
269                    MemA[address,4] = bits(32) UNKNOWN;
270                else
271                    MemA[address,4] = R[i];
272                address = address + 4;
273            }
274        }
275
276        if (registers<15> == '1') // Only possible for encoding A1 or A2
277            MemA[address,4] = PCStoreValue();
278
279        SP = SP - 4*BitCount(registers);
280    }
281#endif
282
283    bool success = false;
284    if (ConditionPassed(opcode))
285    {
286        const uint32_t addr_byte_size = GetAddressByteSize();
287        const addr_t sp = ReadCoreReg (SP_REG, &success);
288        if (!success)
289            return false;
290        uint32_t registers = 0;
291        uint32_t Rt; // the source register
292        switch (encoding) {
293        case eEncodingT1:
294            registers = Bits32(opcode, 7, 0);
295            // The M bit represents LR.
296            if (Bit32(opcode, 8))
297                registers |= (1u << 14);
298            // if BitCount(registers) < 1 then UNPREDICTABLE;
299            if (BitCount(registers) < 1)
300                return false;
301            break;
302        case eEncodingT2:
303            // Ignore bits 15 & 13.
304            registers = Bits32(opcode, 15, 0) & ~0xa000;
305            // if BitCount(registers) < 2 then UNPREDICTABLE;
306            if (BitCount(registers) < 2)
307                return false;
308            break;
309        case eEncodingT3:
310            Rt = Bits32(opcode, 15, 12);
311            // if BadReg(t) then UNPREDICTABLE;
312            if (BadReg(Rt))
313                return false;
314            registers = (1u << Rt);
315            break;
316        case eEncodingA1:
317            registers = Bits32(opcode, 15, 0);
318            // Instead of return false, let's handle the following case as well,
319            // which amounts to pushing one reg onto the full descending stacks.
320            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
321            break;
322        case eEncodingA2:
323            Rt = Bits32(opcode, 15, 12);
324            // if t == 13 then UNPREDICTABLE;
325            if (Rt == dwarf_sp)
326                return false;
327            registers = (1u << Rt);
328            break;
329        default:
330            return false;
331        }
332        addr_t sp_offset = addr_byte_size * BitCount (registers);
333        addr_t addr = sp - sp_offset;
334        uint32_t i;
335
336        EmulateInstruction::Context context;
337        context.type = EmulateInstruction::eContextPushRegisterOnStack;
338        Register dwarf_reg;
339        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
340        Register sp_reg;
341        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
342        for (i=0; i<15; ++i)
343        {
344            if (BitIsSet (registers, i))
345            {
346                dwarf_reg.num = dwarf_r0 + i;
347                context.SetRegisterToRegisterPlusOffset (dwarf_reg, sp_reg, addr - sp);
348                uint32_t reg_value = ReadCoreReg(i, &success);
349                if (!success)
350                    return false;
351                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
352                    return false;
353                addr += addr_byte_size;
354            }
355        }
356
357        if (BitIsSet (registers, 15))
358        {
359            dwarf_reg.num = dwarf_pc;
360            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
361            const uint32_t pc = ReadCoreReg(PC_REG, &success);
362            if (!success)
363                return false;
364            if (!MemAWrite (context, addr, pc, addr_byte_size))
365                return false;
366        }
367
368        context.type = EmulateInstruction::eContextAdjustStackPointer;
369        context.SetImmediateSigned (-sp_offset);
370
371        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
372            return false;
373    }
374    return true;
375}
376
377// Pop Multiple Registers loads multiple registers from the stack, loading from
378// consecutive memory locations staring at the address in SP, and updates
379// SP to point just above the loaded data.
380bool
381EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
382{
383#if 0
384    // ARM pseudo code...
385    if (ConditionPassed())
386    {
387        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
388        address = SP;
389        for i = 0 to 14
390            if registers<i> == '1' then
391                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
392        if registers<15> == '1' then
393            if UnalignedAllowed then
394                LoadWritePC(MemU[address,4]);
395            else
396                LoadWritePC(MemA[address,4]);
397        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
398        if registers<13> == '1' then SP = bits(32) UNKNOWN;
399    }
400#endif
401
402    bool success = false;
403
404    if (ConditionPassed(opcode))
405    {
406        const uint32_t addr_byte_size = GetAddressByteSize();
407        const addr_t sp = ReadCoreReg (SP_REG, &success);
408        if (!success)
409            return false;
410        uint32_t registers = 0;
411        uint32_t Rt; // the destination register
412        switch (encoding) {
413        case eEncodingT1:
414            registers = Bits32(opcode, 7, 0);
415            // The P bit represents PC.
416            if (Bit32(opcode, 8))
417                registers |= (1u << 15);
418            // if BitCount(registers) < 1 then UNPREDICTABLE;
419            if (BitCount(registers) < 1)
420                return false;
421            break;
422        case eEncodingT2:
423            // Ignore bit 13.
424            registers = Bits32(opcode, 15, 0) & ~0x2000;
425            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
426            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
427                return false;
428            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
429            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
430                return false;
431            break;
432        case eEncodingT3:
433            Rt = Bits32(opcode, 15, 12);
434            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
435            if (Rt == 13)
436                return false;
437            if (Rt == 15 && InITBlock() && !LastInITBlock())
438                return false;
439            registers = (1u << Rt);
440            break;
441        case eEncodingA1:
442            registers = Bits32(opcode, 15, 0);
443            // Instead of return false, let's handle the following case as well,
444            // which amounts to popping one reg from the full descending stacks.
445            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
446
447            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
448            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
449                return false;
450            break;
451        case eEncodingA2:
452            Rt = Bits32(opcode, 15, 12);
453            // if t == 13 then UNPREDICTABLE;
454            if (Rt == dwarf_sp)
455                return false;
456            registers = (1u << Rt);
457            break;
458        default:
459            return false;
460        }
461        addr_t sp_offset = addr_byte_size * BitCount (registers);
462        addr_t addr = sp;
463        uint32_t i, data;
464
465        EmulateInstruction::Context context;
466        context.type = EmulateInstruction::eContextPopRegisterOffStack;
467        Register dwarf_reg;
468        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
469        Register sp_reg;
470        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
471        for (i=0; i<15; ++i)
472        {
473            if (BitIsSet (registers, i))
474            {
475                dwarf_reg.num = dwarf_r0 + i;
476                context.SetRegisterPlusOffset (sp_reg, addr - sp);
477                data = MemARead(context, addr, 4, 0, &success);
478                if (!success)
479                    return false;
480                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
481                    return false;
482                addr += addr_byte_size;
483            }
484        }
485
486        if (BitIsSet (registers, 15))
487        {
488            dwarf_reg.num = dwarf_pc;
489            context.SetRegisterPlusOffset (sp_reg, addr - sp);
490            data = MemARead(context, addr, 4, 0, &success);
491            if (!success)
492                return false;
493            // In ARMv5T and above, this is an interworking branch.
494            if (!LoadWritePC(context, data))
495                return false;
496            addr += addr_byte_size;
497        }
498
499        context.type = EmulateInstruction::eContextAdjustStackPointer;
500        context.SetImmediateSigned (sp_offset);
501
502        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
503            return false;
504    }
505    return true;
506}
507
508// Set r7 or ip to point to saved value residing within the stack.
509// ADD (SP plus immediate)
510bool
511EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
512{
513#if 0
514    // ARM pseudo code...
515    if (ConditionPassed())
516    {
517        EncodingSpecificOperations();
518        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
519        if d == 15 then
520           ALUWritePC(result); // setflags is always FALSE here
521        else
522            R[d] = result;
523            if setflags then
524                APSR.N = result<31>;
525                APSR.Z = IsZeroBit(result);
526                APSR.C = carry;
527                APSR.V = overflow;
528    }
529#endif
530
531    bool success = false;
532
533    if (ConditionPassed(opcode))
534    {
535        const addr_t sp = ReadCoreReg (SP_REG, &success);
536        if (!success)
537            return false;
538        uint32_t Rd; // the destination register
539        uint32_t imm32;
540        switch (encoding) {
541        case eEncodingT1:
542            Rd = 7;
543            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
544            break;
545        case eEncodingA1:
546            Rd = Bits32(opcode, 15, 12);
547            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
548            break;
549        default:
550            return false;
551        }
552        addr_t sp_offset = imm32;
553        addr_t addr = sp + sp_offset; // a pointer to the stack area
554
555        EmulateInstruction::Context context;
556        context.type = EmulateInstruction::eContextAdjustStackPointer;
557        Register sp_reg;
558        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
559        context.SetRegisterPlusOffset (sp_reg, sp_offset);
560
561        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
562            return false;
563    }
564    return true;
565}
566
567// Set r7 or ip to the current stack pointer.
568// MOV (register)
569bool
570EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
571{
572#if 0
573    // ARM pseudo code...
574    if (ConditionPassed())
575    {
576        EncodingSpecificOperations();
577        result = R[m];
578        if d == 15 then
579            ALUWritePC(result); // setflags is always FALSE here
580        else
581            R[d] = result;
582            if setflags then
583                APSR.N = result<31>;
584                APSR.Z = IsZeroBit(result);
585                // APSR.C unchanged
586                // APSR.V unchanged
587    }
588#endif
589
590    bool success = false;
591
592    if (ConditionPassed(opcode))
593    {
594        const addr_t sp = ReadCoreReg (SP_REG, &success);
595        if (!success)
596            return false;
597        uint32_t Rd; // the destination register
598        switch (encoding) {
599        case eEncodingT1:
600            Rd = 7;
601            break;
602        case eEncodingA1:
603            Rd = 12;
604            break;
605        default:
606            return false;
607        }
608
609        EmulateInstruction::Context context;
610        context.type = EmulateInstruction::eContextRegisterPlusOffset;
611        Register sp_reg;
612        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
613        context.SetRegisterPlusOffset (sp_reg, 0);
614
615        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
616            return false;
617    }
618    return true;
619}
620
621// Move from high register (r8-r15) to low register (r0-r7).
622// MOV (register)
623bool
624EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
625{
626    return EmulateMOVRdRm (opcode, encoding);
627}
628
629// Move from register to register.
630// MOV (register)
631bool
632EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
633{
634#if 0
635    // ARM pseudo code...
636    if (ConditionPassed())
637    {
638        EncodingSpecificOperations();
639        result = R[m];
640        if d == 15 then
641            ALUWritePC(result); // setflags is always FALSE here
642        else
643            R[d] = result;
644            if setflags then
645                APSR.N = result<31>;
646                APSR.Z = IsZeroBit(result);
647                // APSR.C unchanged
648                // APSR.V unchanged
649    }
650#endif
651
652    bool success = false;
653
654    if (ConditionPassed(opcode))
655    {
656        uint32_t Rm; // the source register
657        uint32_t Rd; // the destination register
658        bool setflags;
659        switch (encoding) {
660        case eEncodingT1:
661            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
662            Rm = Bits32(opcode, 6, 3);
663            setflags = false;
664            if (Rd == 15 && InITBlock() && !LastInITBlock())
665                return false;
666            break;
667        case eEncodingT2:
668            Rd = Bits32(opcode, 2, 0);
669            Rm = Bits32(opcode, 5, 3);
670            setflags = true;
671            if (InITBlock())
672                return false;
673            break;
674        case eEncodingT3:
675            Rd = Bits32(opcode, 11, 8);
676            Rm = Bits32(opcode, 3, 0);
677            setflags = BitIsSet(opcode, 20);
678            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
679            if (setflags && (BadReg(Rd) || BadReg(Rm)))
680                return false;
681            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
682            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
683                return false;
684            break;
685        case eEncodingA1:
686            Rd = Bits32(opcode, 15, 12);
687            Rm = Bits32(opcode, 3, 0);
688            setflags = BitIsSet(opcode, 20);
689
690            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
691            if (Rd == 15 && setflags)
692                return EmulateSUBSPcLrEtc (opcode, encoding);
693            break;
694        default:
695            return false;
696        }
697        uint32_t result = ReadCoreReg(Rm, &success);
698        if (!success)
699            return false;
700
701        // The context specifies that Rm is to be moved into Rd.
702        EmulateInstruction::Context context;
703        context.type = EmulateInstruction::eContextRegisterLoad;
704        Register dwarf_reg;
705        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
706        context.SetRegister (dwarf_reg);
707
708        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
709            return false;
710    }
711    return true;
712}
713
714// Move (immediate) writes an immediate value to the destination register.  It
715// can optionally update the condition flags based on the value.
716// MOV (immediate)
717bool
718EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
719{
720#if 0
721    // ARM pseudo code...
722    if (ConditionPassed())
723    {
724        EncodingSpecificOperations();
725        result = imm32;
726        if d == 15 then         // Can only occur for ARM encoding
727            ALUWritePC(result); // setflags is always FALSE here
728        else
729            R[d] = result;
730            if setflags then
731                APSR.N = result<31>;
732                APSR.Z = IsZeroBit(result);
733                APSR.C = carry;
734                // APSR.V unchanged
735    }
736#endif
737
738    if (ConditionPassed(opcode))
739    {
740        uint32_t Rd; // the destination register
741        uint32_t imm32; // the immediate value to be written to Rd
742        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
743        bool setflags;
744        switch (encoding) {
745            case eEncodingT1:
746                Rd = Bits32(opcode, 10, 8);
747                setflags = !InITBlock();
748                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
749                carry = APSR_C;
750
751                break;
752
753            case eEncodingT2:
754                Rd = Bits32(opcode, 11, 8);
755                setflags = BitIsSet(opcode, 20);
756                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
757                if (BadReg(Rd))
758                  return false;
759
760                break;
761
762            case eEncodingT3:
763            {
764                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
765                Rd = Bits32 (opcode, 11, 8);
766                setflags = false;
767                uint32_t imm4 = Bits32 (opcode, 19, 16);
768                uint32_t imm3 = Bits32 (opcode, 14, 12);
769                uint32_t i = Bit32 (opcode, 26);
770                uint32_t imm8 = Bits32 (opcode, 7, 0);
771                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
772
773                // if BadReg(d) then UNPREDICTABLE;
774                if (BadReg (Rd))
775                    return false;
776            }
777                break;
778
779            case eEncodingA1:
780                // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
781                Rd = Bits32 (opcode, 15, 12);
782                setflags = BitIsSet (opcode, 20);
783                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
784
785                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
786                if ((Rd == 15) && setflags)
787                    return EmulateSUBSPcLrEtc (opcode, encoding);
788
789                break;
790
791            case eEncodingA2:
792            {
793                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
794                Rd = Bits32 (opcode, 15, 12);
795                setflags = false;
796                uint32_t imm4 = Bits32 (opcode, 19, 16);
797                uint32_t imm12 = Bits32 (opcode, 11, 0);
798                imm32 = (imm4 << 12) | imm12;
799
800                // if d == 15 then UNPREDICTABLE;
801                if (Rd == 15)
802                    return false;
803            }
804                break;
805
806            default:
807                return false;
808        }
809        uint32_t result = imm32;
810
811        // The context specifies that an immediate is to be moved into Rd.
812        EmulateInstruction::Context context;
813        context.type = EmulateInstruction::eContextImmediate;
814        context.SetNoArgs ();
815
816        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
817            return false;
818    }
819    return true;
820}
821
822// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
823// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
824// unsigned values.
825//
826// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
827// limited to only a few forms of the instruction.
828bool
829EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
830{
831#if 0
832    if ConditionPassed() then
833        EncodingSpecificOperations();
834        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
835        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
836        result = operand1 * operand2;
837        R[d] = result<31:0>;
838        if setflags then
839            APSR.N = result<31>;
840            APSR.Z = IsZeroBit(result);
841            if ArchVersion() == 4 then
842                APSR.C = bit UNKNOWN;
843            // else APSR.C unchanged
844            // APSR.V always unchanged
845#endif
846
847    if (ConditionPassed(opcode))
848    {
849        uint32_t d;
850        uint32_t n;
851        uint32_t m;
852        bool setflags;
853
854        // EncodingSpecificOperations();
855        switch (encoding)
856        {
857            case eEncodingT1:
858                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
859                d = Bits32 (opcode, 2, 0);
860                n = Bits32 (opcode, 5, 3);
861                m = Bits32 (opcode, 2, 0);
862                setflags = !InITBlock();
863
864                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
865                if ((ArchVersion() < ARMv6) && (d == n))
866                    return false;
867
868                break;
869
870            case eEncodingT2:
871                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
872                d = Bits32 (opcode, 11, 8);
873                n = Bits32 (opcode, 19, 16);
874                m = Bits32 (opcode, 3, 0);
875                setflags = false;
876
877                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
878                if (BadReg (d) || BadReg (n) || BadReg (m))
879                    return false;
880
881                break;
882
883            case eEncodingA1:
884                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
885                d = Bits32 (opcode, 19, 16);
886                n = Bits32 (opcode, 3, 0);
887                m = Bits32 (opcode, 11, 8);
888                setflags = BitIsSet (opcode, 20);
889
890                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
891                if ((d == 15) ||  (n == 15) || (m == 15))
892                    return false;
893
894                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
895                if ((ArchVersion() < ARMv6) && (d == n))
896                    return false;
897
898                break;
899
900            default:
901                return false;
902        }
903
904        bool success = false;
905
906        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
907        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
908        if (!success)
909            return false;
910
911        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
912        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
913        if (!success)
914            return false;
915
916        // result = operand1 * operand2;
917        uint64_t result = operand1 * operand2;
918
919        // R[d] = result<31:0>;
920        Register op1_reg;
921        Register op2_reg;
922        op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
923        op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
924
925        EmulateInstruction::Context context;
926        context.type = eContextMultiplication;
927        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
928
929        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
930            return false;
931
932        // if setflags then
933        if (setflags)
934        {
935            // APSR.N = result<31>;
936            // APSR.Z = IsZeroBit(result);
937            m_new_inst_cpsr = m_opcode_cpsr;
938            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
939            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
940            if (m_new_inst_cpsr != m_opcode_cpsr)
941            {
942                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
943                    return false;
944            }
945
946            // if ArchVersion() == 4 then
947                // APSR.C = bit UNKNOWN;
948        }
949    }
950    return true;
951}
952
953// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
954// It can optionally update the condition flags based on the value.
955bool
956EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
957{
958#if 0
959    // ARM pseudo code...
960    if (ConditionPassed())
961    {
962        EncodingSpecificOperations();
963        result = NOT(imm32);
964        if d == 15 then         // Can only occur for ARM encoding
965            ALUWritePC(result); // setflags is always FALSE here
966        else
967            R[d] = result;
968            if setflags then
969                APSR.N = result<31>;
970                APSR.Z = IsZeroBit(result);
971                APSR.C = carry;
972                // APSR.V unchanged
973    }
974#endif
975
976    if (ConditionPassed(opcode))
977    {
978        uint32_t Rd; // the destination register
979        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
980        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
981        bool setflags;
982        switch (encoding) {
983        case eEncodingT1:
984            Rd = Bits32(opcode, 11, 8);
985            setflags = BitIsSet(opcode, 20);
986            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
987            break;
988        case eEncodingA1:
989            Rd = Bits32(opcode, 15, 12);
990            setflags = BitIsSet(opcode, 20);
991            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
992
993            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
994            if (Rd == 15 && setflags)
995                return EmulateSUBSPcLrEtc (opcode, encoding);
996            break;
997        default:
998            return false;
999        }
1000        uint32_t result = ~imm32;
1001
1002        // The context specifies that an immediate is to be moved into Rd.
1003        EmulateInstruction::Context context;
1004        context.type = EmulateInstruction::eContextImmediate;
1005        context.SetNoArgs ();
1006
1007        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1008            return false;
1009    }
1010    return true;
1011}
1012
1013// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1014// It can optionally update the condition flags based on the result.
1015bool
1016EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1017{
1018#if 0
1019    // ARM pseudo code...
1020    if (ConditionPassed())
1021    {
1022        EncodingSpecificOperations();
1023        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1024        result = NOT(shifted);
1025        if d == 15 then         // Can only occur for ARM encoding
1026            ALUWritePC(result); // setflags is always FALSE here
1027        else
1028            R[d] = result;
1029            if setflags then
1030                APSR.N = result<31>;
1031                APSR.Z = IsZeroBit(result);
1032                APSR.C = carry;
1033                // APSR.V unchanged
1034    }
1035#endif
1036
1037    if (ConditionPassed(opcode))
1038    {
1039        uint32_t Rm; // the source register
1040        uint32_t Rd; // the destination register
1041        ARM_ShifterType shift_t;
1042        uint32_t shift_n; // the shift applied to the value read from Rm
1043        bool setflags;
1044        uint32_t carry; // the carry bit after the shift operation
1045        switch (encoding) {
1046        case eEncodingT1:
1047            Rd = Bits32(opcode, 2, 0);
1048            Rm = Bits32(opcode, 5, 3);
1049            setflags = !InITBlock();
1050            shift_t = SRType_LSL;
1051            shift_n = 0;
1052            if (InITBlock())
1053                return false;
1054            break;
1055        case eEncodingT2:
1056            Rd = Bits32(opcode, 11, 8);
1057            Rm = Bits32(opcode, 3, 0);
1058            setflags = BitIsSet(opcode, 20);
1059            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1060            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1061            if (BadReg(Rd) || BadReg(Rm))
1062                return false;
1063            break;
1064        case eEncodingA1:
1065            Rd = Bits32(opcode, 15, 12);
1066            Rm = Bits32(opcode, 3, 0);
1067            setflags = BitIsSet(opcode, 20);
1068            shift_n = DecodeImmShiftARM(opcode, shift_t);
1069            break;
1070        default:
1071            return false;
1072        }
1073        bool success = false;
1074        uint32_t value = ReadCoreReg(Rm, &success);
1075        if (!success)
1076            return false;
1077
1078        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry);
1079        uint32_t result = ~shifted;
1080
1081        // The context specifies that an immediate is to be moved into Rd.
1082        EmulateInstruction::Context context;
1083        context.type = EmulateInstruction::eContextImmediate;
1084        context.SetNoArgs ();
1085
1086        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1087            return false;
1088    }
1089    return true;
1090}
1091
1092// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1093// LDR (literal)
1094bool
1095EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1096{
1097#if 0
1098    // ARM pseudo code...
1099    if (ConditionPassed())
1100    {
1101        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1102        base = Align(PC,4);
1103        address = if add then (base + imm32) else (base - imm32);
1104        data = MemU[address,4];
1105        if t == 15 then
1106            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1107        elsif UnalignedSupport() || address<1:0> = '00' then
1108            R[t] = data;
1109        else // Can only apply before ARMv7
1110            if CurrentInstrSet() == InstrSet_ARM then
1111                R[t] = ROR(data, 8*UInt(address<1:0>));
1112            else
1113                R[t] = bits(32) UNKNOWN;
1114    }
1115#endif
1116
1117    if (ConditionPassed(opcode))
1118    {
1119        bool success = false;
1120        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1121        if (!success)
1122            return false;
1123
1124        // PC relative immediate load context
1125        EmulateInstruction::Context context;
1126        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1127        Register pc_reg;
1128        pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1129        context.SetRegisterPlusOffset (pc_reg, 0);
1130
1131        uint32_t Rt;    // the destination register
1132        uint32_t imm32; // immediate offset from the PC
1133        bool add;       // +imm32 or -imm32?
1134        addr_t base;    // the base address
1135        addr_t address; // the PC relative address
1136        uint32_t data;  // the literal data value from the PC relative load
1137        switch (encoding) {
1138        case eEncodingT1:
1139            Rt = Bits32(opcode, 10, 8);
1140            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1141            add = true;
1142            break;
1143        case eEncodingT2:
1144            Rt = Bits32(opcode, 15, 12);
1145            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1146            add = BitIsSet(opcode, 23);
1147            if (Rt == 15 && InITBlock() && !LastInITBlock())
1148                return false;
1149            break;
1150        default:
1151            return false;
1152        }
1153
1154        base = Align(pc, 4);
1155        if (add)
1156            address = base + imm32;
1157        else
1158            address = base - imm32;
1159
1160        context.SetRegisterPlusOffset(pc_reg, address - base);
1161        data = MemURead(context, address, 4, 0, &success);
1162        if (!success)
1163            return false;
1164
1165        if (Rt == 15)
1166        {
1167            if (Bits32(address, 1, 0) == 0)
1168            {
1169                // In ARMv5T and above, this is an interworking branch.
1170                if (!LoadWritePC(context, data))
1171                    return false;
1172            }
1173            else
1174                return false;
1175        }
1176        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1177        {
1178            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1179                return false;
1180        }
1181        else // We don't handle ARM for now.
1182            return false;
1183
1184    }
1185    return true;
1186}
1187
1188// An add operation to adjust the SP.
1189// ADD (SP plus immediate)
1190bool
1191EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1192{
1193#if 0
1194    // ARM pseudo code...
1195    if (ConditionPassed())
1196    {
1197        EncodingSpecificOperations();
1198        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1199        if d == 15 then // Can only occur for ARM encoding
1200            ALUWritePC(result); // setflags is always FALSE here
1201        else
1202            R[d] = result;
1203            if setflags then
1204                APSR.N = result<31>;
1205                APSR.Z = IsZeroBit(result);
1206                APSR.C = carry;
1207                APSR.V = overflow;
1208    }
1209#endif
1210
1211    bool success = false;
1212
1213    if (ConditionPassed(opcode))
1214    {
1215        const addr_t sp = ReadCoreReg (SP_REG, &success);
1216        if (!success)
1217            return false;
1218        uint32_t imm32; // the immediate operand
1219        uint32_t d;
1220        bool setflags;
1221        switch (encoding)
1222        {
1223            case eEncodingT1:
1224                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1225                d = Bits32 (opcode, 10, 8);
1226                setflags = false;
1227                imm32 = (Bits32 (opcode, 7, 0) << 2);
1228
1229                break;
1230
1231            case eEncodingT2:
1232                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1233                d = 13;
1234                setflags = false;
1235                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1236
1237                break;
1238
1239            default:
1240                return false;
1241        }
1242        addr_t sp_offset = imm32;
1243        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1244
1245        EmulateInstruction::Context context;
1246        context.type = EmulateInstruction::eContextAdjustStackPointer;
1247        Register sp_reg;
1248        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1249        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1250
1251        if (d == 15)
1252        {
1253            if (!ALUWritePC (context, addr))
1254                return false;
1255        }
1256        else
1257        {
1258            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1259                return false;
1260        }
1261    }
1262    return true;
1263}
1264
1265// An add operation to adjust the SP.
1266// ADD (SP plus register)
1267bool
1268EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1269{
1270#if 0
1271    // ARM pseudo code...
1272    if (ConditionPassed())
1273    {
1274        EncodingSpecificOperations();
1275        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1276        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1277        if d == 15 then
1278            ALUWritePC(result); // setflags is always FALSE here
1279        else
1280            R[d] = result;
1281            if setflags then
1282                APSR.N = result<31>;
1283                APSR.Z = IsZeroBit(result);
1284                APSR.C = carry;
1285                APSR.V = overflow;
1286    }
1287#endif
1288
1289    bool success = false;
1290
1291    if (ConditionPassed(opcode))
1292    {
1293        const addr_t sp = ReadCoreReg (SP_REG, &success);
1294        if (!success)
1295            return false;
1296        uint32_t Rm; // the second operand
1297        switch (encoding) {
1298        case eEncodingT2:
1299            Rm = Bits32(opcode, 6, 3);
1300            break;
1301        default:
1302            return false;
1303        }
1304        int32_t reg_value = ReadCoreReg(Rm, &success);
1305        if (!success)
1306            return false;
1307
1308        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1309
1310        EmulateInstruction::Context context;
1311        context.type = EmulateInstruction::eContextAddition;
1312        Register sp_reg;
1313        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1314        Register other_reg;
1315        other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1316        context.SetRegisterRegisterOperands (sp_reg, other_reg);
1317
1318        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1319            return false;
1320    }
1321    return true;
1322}
1323
1324// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1325// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1326// from Thumb to ARM.
1327// BLX (immediate)
1328bool
1329EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1330{
1331#if 0
1332    // ARM pseudo code...
1333    if (ConditionPassed())
1334    {
1335        EncodingSpecificOperations();
1336        if CurrentInstrSet() == InstrSet_ARM then
1337            LR = PC - 4;
1338        else
1339            LR = PC<31:1> : '1';
1340        if targetInstrSet == InstrSet_ARM then
1341            targetAddress = Align(PC,4) + imm32;
1342        else
1343            targetAddress = PC + imm32;
1344        SelectInstrSet(targetInstrSet);
1345        BranchWritePC(targetAddress);
1346    }
1347#endif
1348
1349    bool success = true;
1350
1351    if (ConditionPassed(opcode))
1352    {
1353        EmulateInstruction::Context context;
1354        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1355        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1356        if (!success)
1357            return false;
1358        addr_t lr; // next instruction address
1359        addr_t target; // target address
1360        int32_t imm32; // PC-relative offset
1361        switch (encoding) {
1362        case eEncodingT1:
1363            {
1364            lr = pc | 1u; // return address
1365            uint32_t S = Bit32(opcode, 26);
1366            uint32_t imm10 = Bits32(opcode, 25, 16);
1367            uint32_t J1 = Bit32(opcode, 13);
1368            uint32_t J2 = Bit32(opcode, 11);
1369            uint32_t imm11 = Bits32(opcode, 10, 0);
1370            uint32_t I1 = !(J1 ^ S);
1371            uint32_t I2 = !(J2 ^ S);
1372            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1373            imm32 = llvm::SignExtend32<25>(imm25);
1374            target = pc + imm32;
1375            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1376            if (InITBlock() && !LastInITBlock())
1377                return false;
1378            break;
1379            }
1380        case eEncodingT2:
1381            {
1382            lr = pc | 1u; // return address
1383            uint32_t S = Bit32(opcode, 26);
1384            uint32_t imm10H = Bits32(opcode, 25, 16);
1385            uint32_t J1 = Bit32(opcode, 13);
1386            uint32_t J2 = Bit32(opcode, 11);
1387            uint32_t imm10L = Bits32(opcode, 10, 1);
1388            uint32_t I1 = !(J1 ^ S);
1389            uint32_t I2 = !(J2 ^ S);
1390            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1391            imm32 = llvm::SignExtend32<25>(imm25);
1392            target = Align(pc, 4) + imm32;
1393            context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1394            if (InITBlock() && !LastInITBlock())
1395                return false;
1396            break;
1397            }
1398        case eEncodingA1:
1399            lr = pc - 4; // return address
1400            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1401            target = Align(pc, 4) + imm32;
1402            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1403            break;
1404        case eEncodingA2:
1405            lr = pc - 4; // return address
1406            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1407            target = pc + imm32;
1408            context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
1409            break;
1410        default:
1411            return false;
1412        }
1413        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1414            return false;
1415        if (!BranchWritePC(context, target))
1416            return false;
1417    }
1418    return true;
1419}
1420
1421// Branch with Link and Exchange (register) calls a subroutine at an address and
1422// instruction set specified by a register.
1423// BLX (register)
1424bool
1425EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1426{
1427#if 0
1428    // ARM pseudo code...
1429    if (ConditionPassed())
1430    {
1431        EncodingSpecificOperations();
1432        target = R[m];
1433        if CurrentInstrSet() == InstrSet_ARM then
1434            next_instr_addr = PC - 4;
1435            LR = next_instr_addr;
1436        else
1437            next_instr_addr = PC - 2;
1438            LR = next_instr_addr<31:1> : '1';
1439        BXWritePC(target);
1440    }
1441#endif
1442
1443    bool success = false;
1444
1445    if (ConditionPassed(opcode))
1446    {
1447        EmulateInstruction::Context context;
1448        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1449        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1450        addr_t lr; // next instruction address
1451        if (!success)
1452            return false;
1453        uint32_t Rm; // the register with the target address
1454        switch (encoding) {
1455        case eEncodingT1:
1456            lr = (pc - 2) | 1u; // return address
1457            Rm = Bits32(opcode, 6, 3);
1458            // if m == 15 then UNPREDICTABLE;
1459            if (Rm == 15)
1460                return false;
1461            if (InITBlock() && !LastInITBlock())
1462                return false;
1463            break;
1464        case eEncodingA1:
1465            lr = pc - 4; // return address
1466            Rm = Bits32(opcode, 3, 0);
1467            // if m == 15 then UNPREDICTABLE;
1468            if (Rm == 15)
1469                return false;
1470            break;
1471        default:
1472            return false;
1473        }
1474        addr_t target = ReadCoreReg (Rm, &success);
1475        if (!success)
1476            return false;
1477        Register dwarf_reg;
1478        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1479        context.SetRegister (dwarf_reg);
1480        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1481            return false;
1482        if (!BXWritePC(context, target))
1483            return false;
1484    }
1485    return true;
1486}
1487
1488// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1489bool
1490EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1491{
1492#if 0
1493    // ARM pseudo code...
1494    if (ConditionPassed())
1495    {
1496        EncodingSpecificOperations();
1497        BXWritePC(R[m]);
1498    }
1499#endif
1500
1501    if (ConditionPassed(opcode))
1502    {
1503        EmulateInstruction::Context context;
1504        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1505        uint32_t Rm; // the register with the target address
1506        switch (encoding) {
1507        case eEncodingT1:
1508            Rm = Bits32(opcode, 6, 3);
1509            if (InITBlock() && !LastInITBlock())
1510                return false;
1511            break;
1512        case eEncodingA1:
1513            Rm = Bits32(opcode, 3, 0);
1514            break;
1515        default:
1516            return false;
1517        }
1518        bool success = false;
1519        addr_t target = ReadCoreReg (Rm, &success);
1520        if (!success)
1521            return false;
1522
1523        Register dwarf_reg;
1524        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1525        context.SetRegister (dwarf_reg);
1526        if (!BXWritePC(context, target))
1527            return false;
1528    }
1529    return true;
1530}
1531
1532// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1533// address and instruction set specified by a register as though it were a BX instruction.
1534//
1535// TODO: Emulate Jazelle architecture?
1536//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1537bool
1538EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1539{
1540#if 0
1541    // ARM pseudo code...
1542    if (ConditionPassed())
1543    {
1544        EncodingSpecificOperations();
1545        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1546            BXWritePC(R[m]);
1547        else
1548            if JazelleAcceptsExecution() then
1549                SwitchToJazelleExecution();
1550            else
1551                SUBARCHITECTURE_DEFINED handler call;
1552    }
1553#endif
1554
1555    if (ConditionPassed(opcode))
1556    {
1557        EmulateInstruction::Context context;
1558        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1559        uint32_t Rm; // the register with the target address
1560        switch (encoding) {
1561        case eEncodingT1:
1562            Rm = Bits32(opcode, 19, 16);
1563            if (BadReg(Rm))
1564                return false;
1565            if (InITBlock() && !LastInITBlock())
1566                return false;
1567            break;
1568        case eEncodingA1:
1569            Rm = Bits32(opcode, 3, 0);
1570            if (Rm == 15)
1571                return false;
1572            break;
1573        default:
1574            return false;
1575        }
1576        bool success = false;
1577        addr_t target = ReadCoreReg (Rm, &success);
1578        if (!success)
1579            return false;
1580
1581        Register dwarf_reg;
1582        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1583        context.SetRegister (dwarf_reg);
1584        if (!BXWritePC(context, target))
1585            return false;
1586    }
1587    return true;
1588}
1589
1590// Set r7 to point to some ip offset.
1591// SUB (immediate)
1592bool
1593EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1594{
1595#if 0
1596    // ARM pseudo code...
1597    if (ConditionPassed())
1598    {
1599        EncodingSpecificOperations();
1600        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1601        if d == 15 then // Can only occur for ARM encoding
1602           ALUWritePC(result); // setflags is always FALSE here
1603        else
1604            R[d] = result;
1605            if setflags then
1606                APSR.N = result<31>;
1607                APSR.Z = IsZeroBit(result);
1608                APSR.C = carry;
1609                APSR.V = overflow;
1610    }
1611#endif
1612
1613    if (ConditionPassed(opcode))
1614    {
1615        bool success = false;
1616        const addr_t ip = ReadCoreReg (12, &success);
1617        if (!success)
1618            return false;
1619        uint32_t imm32;
1620        switch (encoding) {
1621        case eEncodingA1:
1622            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1623            break;
1624        default:
1625            return false;
1626        }
1627        addr_t ip_offset = imm32;
1628        addr_t addr = ip - ip_offset; // the adjusted ip value
1629
1630        EmulateInstruction::Context context;
1631        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1632        Register dwarf_reg;
1633        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
1634        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1635
1636        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1637            return false;
1638    }
1639    return true;
1640}
1641
1642// Set ip to point to some stack offset.
1643// SUB (SP minus immediate)
1644bool
1645EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1646{
1647#if 0
1648    // ARM pseudo code...
1649    if (ConditionPassed())
1650    {
1651        EncodingSpecificOperations();
1652        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1653        if d == 15 then // Can only occur for ARM encoding
1654           ALUWritePC(result); // setflags is always FALSE here
1655        else
1656            R[d] = result;
1657            if setflags then
1658                APSR.N = result<31>;
1659                APSR.Z = IsZeroBit(result);
1660                APSR.C = carry;
1661                APSR.V = overflow;
1662    }
1663#endif
1664
1665    if (ConditionPassed(opcode))
1666    {
1667        bool success = false;
1668        const addr_t sp = ReadCoreReg (SP_REG, &success);
1669        if (!success)
1670            return false;
1671        uint32_t imm32;
1672        switch (encoding) {
1673        case eEncodingA1:
1674            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1675            break;
1676        default:
1677            return false;
1678        }
1679        addr_t sp_offset = imm32;
1680        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1681
1682        EmulateInstruction::Context context;
1683        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1684        Register dwarf_reg;
1685        dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1686        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1687
1688        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1689            return false;
1690    }
1691    return true;
1692}
1693
1694// This instruction subtracts an immediate value from the SP value, and writes
1695// the result to the destination register.
1696//
1697// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1698bool
1699EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1700{
1701#if 0
1702    // ARM pseudo code...
1703    if (ConditionPassed())
1704    {
1705        EncodingSpecificOperations();
1706        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1707        if d == 15 then        // Can only occur for ARM encoding
1708           ALUWritePC(result); // setflags is always FALSE here
1709        else
1710            R[d] = result;
1711            if setflags then
1712                APSR.N = result<31>;
1713                APSR.Z = IsZeroBit(result);
1714                APSR.C = carry;
1715                APSR.V = overflow;
1716    }
1717#endif
1718
1719    bool success = false;
1720    if (ConditionPassed(opcode))
1721    {
1722        const addr_t sp = ReadCoreReg (SP_REG, &success);
1723        if (!success)
1724            return false;
1725
1726        uint32_t Rd;
1727        bool setflags;
1728        uint32_t imm32;
1729        switch (encoding) {
1730        case eEncodingT1:
1731            Rd = 13;
1732            setflags = false;
1733            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1734            break;
1735        case eEncodingT2:
1736            Rd = Bits32(opcode, 11, 8);
1737            setflags = BitIsSet(opcode, 20);
1738            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1739            if (Rd == 15 && setflags)
1740                return EmulateCMPImm(opcode, eEncodingT2);
1741            if (Rd == 15 && !setflags)
1742                return false;
1743            break;
1744        case eEncodingT3:
1745            Rd = Bits32(opcode, 11, 8);
1746            setflags = false;
1747            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1748            if (Rd == 15)
1749                return false;
1750            break;
1751        case eEncodingA1:
1752            Rd = Bits32(opcode, 15, 12);
1753            setflags = BitIsSet(opcode, 20);
1754            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1755
1756            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1757            if (Rd == 15 && setflags)
1758                return EmulateSUBSPcLrEtc (opcode, encoding);
1759            break;
1760        default:
1761            return false;
1762        }
1763        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1764
1765        EmulateInstruction::Context context;
1766        if (Rd == 13)
1767        {
1768            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1769                                     // value gets passed down to context.SetImmediateSigned.
1770            context.type = EmulateInstruction::eContextAdjustStackPointer;
1771            context.SetImmediateSigned (-imm64); // the stack pointer offset
1772        }
1773        else
1774        {
1775            context.type = EmulateInstruction::eContextImmediate;
1776            context.SetNoArgs ();
1777        }
1778
1779        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1780            return false;
1781    }
1782    return true;
1783}
1784
1785// A store operation to the stack that also updates the SP.
1786bool
1787EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1788{
1789#if 0
1790    // ARM pseudo code...
1791    if (ConditionPassed())
1792    {
1793        EncodingSpecificOperations();
1794        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1795        address = if index then offset_addr else R[n];
1796        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1797        if wback then R[n] = offset_addr;
1798    }
1799#endif
1800
1801    bool success = false;
1802
1803    if (ConditionPassed(opcode))
1804    {
1805        const uint32_t addr_byte_size = GetAddressByteSize();
1806        const addr_t sp = ReadCoreReg (SP_REG, &success);
1807        if (!success)
1808            return false;
1809        uint32_t Rt; // the source register
1810        uint32_t imm12;
1811        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1812
1813        bool index;
1814        bool add;
1815        bool wback;
1816        switch (encoding) {
1817        case eEncodingA1:
1818            Rt = Bits32(opcode, 15, 12);
1819            imm12 = Bits32(opcode, 11, 0);
1820            Rn = Bits32 (opcode, 19, 16);
1821
1822            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1823                return false;
1824
1825            index = BitIsSet (opcode, 24);
1826            add = BitIsSet (opcode, 23);
1827            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1828
1829            if (wback && ((Rn == 15) || (Rn == Rt)))
1830                return false;
1831            break;
1832        default:
1833            return false;
1834        }
1835        addr_t offset_addr;
1836        if (add)
1837            offset_addr = sp + imm12;
1838        else
1839            offset_addr = sp - imm12;
1840
1841        addr_t addr;
1842        if (index)
1843            addr = offset_addr;
1844        else
1845            addr = sp;
1846
1847        EmulateInstruction::Context context;
1848        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1849        Register sp_reg;
1850        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1851        context.SetRegisterPlusOffset (sp_reg, addr - sp);
1852        if (Rt != 15)
1853        {
1854            uint32_t reg_value = ReadCoreReg(Rt, &success);
1855            if (!success)
1856                return false;
1857            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1858                return false;
1859        }
1860        else
1861        {
1862            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1863            if (!success)
1864                return false;
1865            if (!MemUWrite (context, addr, pc, addr_byte_size))
1866                return false;
1867        }
1868
1869
1870        if (wback)
1871        {
1872            context.type = EmulateInstruction::eContextAdjustStackPointer;
1873            context.SetImmediateSigned (addr - sp);
1874            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1875                return false;
1876        }
1877    }
1878    return true;
1879}
1880
1881// Vector Push stores multiple extension registers to the stack.
1882// It also updates SP to point to the start of the stored data.
1883bool
1884EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1885{
1886#if 0
1887    // ARM pseudo code...
1888    if (ConditionPassed())
1889    {
1890        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1891        address = SP - imm32;
1892        SP = SP - imm32;
1893        if single_regs then
1894            for r = 0 to regs-1
1895                MemA[address,4] = S[d+r]; address = address+4;
1896        else
1897            for r = 0 to regs-1
1898                // Store as two word-aligned words in the correct order for current endianness.
1899                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1900                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1901                address = address+8;
1902    }
1903#endif
1904
1905    bool success = false;
1906
1907    if (ConditionPassed(opcode))
1908    {
1909        const uint32_t addr_byte_size = GetAddressByteSize();
1910        const addr_t sp = ReadCoreReg (SP_REG, &success);
1911        if (!success)
1912            return false;
1913        bool single_regs;
1914        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1915        uint32_t imm32; // stack offset
1916        uint32_t regs;  // number of registers
1917        switch (encoding) {
1918        case eEncodingT1:
1919        case eEncodingA1:
1920            single_regs = false;
1921            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1922            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1923            // If UInt(imm8) is odd, see "FSTMX".
1924            regs = Bits32(opcode, 7, 0) / 2;
1925            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1926            if (regs == 0 || regs > 16 || (d + regs) > 32)
1927                return false;
1928            break;
1929        case eEncodingT2:
1930        case eEncodingA2:
1931            single_regs = true;
1932            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1933            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1934            regs = Bits32(opcode, 7, 0);
1935            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1936            if (regs == 0 || regs > 16 || (d + regs) > 32)
1937                return false;
1938            break;
1939        default:
1940            return false;
1941        }
1942        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1943        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1944        addr_t sp_offset = imm32;
1945        addr_t addr = sp - sp_offset;
1946        uint32_t i;
1947
1948        EmulateInstruction::Context context;
1949        context.type = EmulateInstruction::eContextPushRegisterOnStack;
1950        Register dwarf_reg;
1951        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1952        Register sp_reg;
1953        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1954        for (i=0; i<regs; ++i)
1955        {
1956            dwarf_reg.num = start_reg + d + i;
1957            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1958            // uint64_t to accommodate 64-bit registers.
1959            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1960            if (!success)
1961                return false;
1962            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1963                return false;
1964            addr += reg_byte_size;
1965        }
1966
1967        context.type = EmulateInstruction::eContextAdjustStackPointer;
1968        context.SetImmediateSigned (-sp_offset);
1969
1970        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1971            return false;
1972    }
1973    return true;
1974}
1975
1976// Vector Pop loads multiple extension registers from the stack.
1977// It also updates SP to point just above the loaded data.
1978bool
1979EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
1980{
1981#if 0
1982    // ARM pseudo code...
1983    if (ConditionPassed())
1984    {
1985        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1986        address = SP;
1987        SP = SP + imm32;
1988        if single_regs then
1989            for r = 0 to regs-1
1990                S[d+r] = MemA[address,4]; address = address+4;
1991        else
1992            for r = 0 to regs-1
1993                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1994                // Combine the word-aligned words in the correct order for current endianness.
1995                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1996    }
1997#endif
1998
1999    bool success = false;
2000
2001    if (ConditionPassed(opcode))
2002    {
2003        const uint32_t addr_byte_size = GetAddressByteSize();
2004        const addr_t sp = ReadCoreReg (SP_REG, &success);
2005        if (!success)
2006            return false;
2007        bool single_regs;
2008        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2009        uint32_t imm32; // stack offset
2010        uint32_t regs;  // number of registers
2011        switch (encoding) {
2012        case eEncodingT1:
2013        case eEncodingA1:
2014            single_regs = false;
2015            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2016            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2017            // If UInt(imm8) is odd, see "FLDMX".
2018            regs = Bits32(opcode, 7, 0) / 2;
2019            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2020            if (regs == 0 || regs > 16 || (d + regs) > 32)
2021                return false;
2022            break;
2023        case eEncodingT2:
2024        case eEncodingA2:
2025            single_regs = true;
2026            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2027            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2028            regs = Bits32(opcode, 7, 0);
2029            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2030            if (regs == 0 || regs > 16 || (d + regs) > 32)
2031                return false;
2032            break;
2033        default:
2034            return false;
2035        }
2036        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2037        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2038        addr_t sp_offset = imm32;
2039        addr_t addr = sp;
2040        uint32_t i;
2041        uint64_t data; // uint64_t to accomodate 64-bit registers.
2042
2043        EmulateInstruction::Context context;
2044        context.type = EmulateInstruction::eContextPopRegisterOffStack;
2045        Register dwarf_reg;
2046        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
2047        Register sp_reg;
2048        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
2049        for (i=0; i<regs; ++i)
2050        {
2051            dwarf_reg.num = start_reg + d + i;
2052            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2053            data = MemARead(context, addr, reg_byte_size, 0, &success);
2054            if (!success)
2055                return false;
2056            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
2057                return false;
2058            addr += reg_byte_size;
2059        }
2060
2061        context.type = EmulateInstruction::eContextAdjustStackPointer;
2062        context.SetImmediateSigned (sp_offset);
2063
2064        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2065            return false;
2066    }
2067    return true;
2068}
2069
2070// SVC (previously SWI)
2071bool
2072EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2073{
2074#if 0
2075    // ARM pseudo code...
2076    if (ConditionPassed())
2077    {
2078        EncodingSpecificOperations();
2079        CallSupervisor();
2080    }
2081#endif
2082
2083    bool success = false;
2084
2085    if (ConditionPassed(opcode))
2086    {
2087        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2088        addr_t lr; // next instruction address
2089        if (!success)
2090            return false;
2091        uint32_t imm32; // the immediate constant
2092        uint32_t mode;  // ARM or Thumb mode
2093        switch (encoding) {
2094        case eEncodingT1:
2095            lr = (pc + 2) | 1u; // return address
2096            imm32 = Bits32(opcode, 7, 0);
2097            mode = eModeThumb;
2098            break;
2099        case eEncodingA1:
2100            lr = pc + 4; // return address
2101            imm32 = Bits32(opcode, 23, 0);
2102            mode = eModeARM;
2103            break;
2104        default:
2105            return false;
2106        }
2107
2108        EmulateInstruction::Context context;
2109        context.type = EmulateInstruction::eContextSupervisorCall;
2110        context.SetModeAndImmediate (mode, imm32);
2111        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2112            return false;
2113    }
2114    return true;
2115}
2116
2117// If Then makes up to four following instructions (the IT block) conditional.
2118bool
2119EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2120{
2121#if 0
2122    // ARM pseudo code...
2123    EncodingSpecificOperations();
2124    ITSTATE.IT<7:0> = firstcond:mask;
2125#endif
2126
2127    m_it_session.InitIT(Bits32(opcode, 7, 0));
2128    return true;
2129}
2130
2131// Branch causes a branch to a target address.
2132bool
2133EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2134{
2135#if 0
2136    // ARM pseudo code...
2137    if (ConditionPassed())
2138    {
2139        EncodingSpecificOperations();
2140        BranchWritePC(PC + imm32);
2141    }
2142#endif
2143
2144    bool success = false;
2145
2146    if (ConditionPassed(opcode))
2147    {
2148        EmulateInstruction::Context context;
2149        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2150        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2151        if (!success)
2152            return false;
2153        addr_t target; // target address
2154        int32_t imm32; // PC-relative offset
2155        switch (encoding) {
2156        case eEncodingT1:
2157            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2158            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2159            target = pc + imm32;
2160            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2161            break;
2162        case eEncodingT2:
2163            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2164            target = pc + imm32;
2165            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2166            break;
2167        case eEncodingT3:
2168            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2169            {
2170            uint32_t S = Bit32(opcode, 26);
2171            uint32_t imm6 = Bits32(opcode, 21, 16);
2172            uint32_t J1 = Bit32(opcode, 13);
2173            uint32_t J2 = Bit32(opcode, 11);
2174            uint32_t imm11 = Bits32(opcode, 10, 0);
2175            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2176            imm32 = llvm::SignExtend32<21>(imm21);
2177            target = pc + imm32;
2178            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2179            break;
2180            }
2181        case eEncodingT4:
2182            {
2183            uint32_t S = Bit32(opcode, 26);
2184            uint32_t imm10 = Bits32(opcode, 25, 16);
2185            uint32_t J1 = Bit32(opcode, 13);
2186            uint32_t J2 = Bit32(opcode, 11);
2187            uint32_t imm11 = Bits32(opcode, 10, 0);
2188            uint32_t I1 = !(J1 ^ S);
2189            uint32_t I2 = !(J2 ^ S);
2190            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2191            imm32 = llvm::SignExtend32<25>(imm25);
2192            target = pc + imm32;
2193            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2194            break;
2195            }
2196        case eEncodingA1:
2197            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2198            target = pc + imm32;
2199            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
2200            break;
2201        default:
2202            return false;
2203        }
2204        if (!BranchWritePC(context, target))
2205            return false;
2206    }
2207    return true;
2208}
2209
2210// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2211// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2212// CBNZ, CBZ
2213bool
2214EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2215{
2216#if 0
2217    // ARM pseudo code...
2218    EncodingSpecificOperations();
2219    if nonzero ^ IsZero(R[n]) then
2220        BranchWritePC(PC + imm32);
2221#endif
2222
2223    bool success = false;
2224
2225    // Read the register value from the operand register Rn.
2226    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2227    if (!success)
2228        return false;
2229
2230    EmulateInstruction::Context context;
2231    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2232    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2233    if (!success)
2234        return false;
2235
2236    addr_t target;  // target address
2237    uint32_t imm32; // PC-relative offset to branch forward
2238    bool nonzero;
2239    switch (encoding) {
2240    case eEncodingT1:
2241        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2242        nonzero = BitIsSet(opcode, 11);
2243        target = pc + imm32;
2244        context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2245        break;
2246    default:
2247        return false;
2248    }
2249    if (nonzero ^ (reg_val == 0))
2250        if (!BranchWritePC(context, target))
2251            return false;
2252
2253    return true;
2254}
2255
2256// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2257// A base register provides a pointer to the table, and a second register supplies an index into the table.
2258// The branch length is twice the value of the byte returned from the table.
2259//
2260// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2261// A base register provides a pointer to the table, and a second register supplies an index into the table.
2262// The branch length is twice the value of the halfword returned from the table.
2263// TBB, TBH
2264bool
2265EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2266{
2267#if 0
2268    // ARM pseudo code...
2269    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2270    if is_tbh then
2271        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2272    else
2273        halfwords = UInt(MemU[R[n]+R[m], 1]);
2274    BranchWritePC(PC + 2*halfwords);
2275#endif
2276
2277    bool success = false;
2278
2279    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2280    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2281    bool is_tbh;     // true if table branch halfword
2282    switch (encoding) {
2283    case eEncodingT1:
2284        Rn = Bits32(opcode, 19, 16);
2285        Rm = Bits32(opcode, 3, 0);
2286        is_tbh = BitIsSet(opcode, 4);
2287        if (Rn == 13 || BadReg(Rm))
2288            return false;
2289        if (InITBlock() && !LastInITBlock())
2290            return false;
2291        break;
2292    default:
2293        return false;
2294    }
2295
2296    // Read the address of the table from the operand register Rn.
2297    // The PC can be used, in which case the table immediately follows this instruction.
2298    uint32_t base = ReadCoreReg(Rm, &success);
2299    if (!success)
2300        return false;
2301
2302    // the table index
2303    uint32_t index = ReadCoreReg(Rm, &success);
2304    if (!success)
2305        return false;
2306
2307    // the offsetted table address
2308    addr_t addr = base + (is_tbh ? index*2 : index);
2309
2310    // PC-relative offset to branch forward
2311    EmulateInstruction::Context context;
2312    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2313    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2314    if (!success)
2315        return false;
2316
2317    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2318    if (!success)
2319        return false;
2320
2321    // target address
2322    addr_t target = pc + offset;
2323    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2324    context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
2325
2326    if (!BranchWritePC(context, target))
2327        return false;
2328
2329    return true;
2330}
2331
2332// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2333// It can optionally update the condition flags based on the result.
2334bool
2335EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2336{
2337#if 0
2338    if ConditionPassed() then
2339        EncodingSpecificOperations();
2340        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2341        R[d] = result;
2342        if setflags then
2343            APSR.N = result<31>;
2344            APSR.Z = IsZeroBit(result);
2345            APSR.C = carry;
2346            APSR.V = overflow;
2347#endif
2348
2349    bool success = false;
2350
2351    if (ConditionPassed(opcode))
2352    {
2353        uint32_t d;
2354        uint32_t n;
2355        bool setflags;
2356        uint32_t imm32;
2357        uint32_t carry_out;
2358
2359        //EncodingSpecificOperations();
2360        switch (encoding)
2361        {
2362            case eEncodingT1:
2363                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2364                d = Bits32 (opcode, 2, 0);
2365                n = Bits32 (opcode, 5, 3);
2366                setflags = !InITBlock();
2367                imm32 = Bits32 (opcode, 8,6);
2368
2369                break;
2370
2371            case eEncodingT2:
2372                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2373                d = Bits32 (opcode, 10, 8);
2374                n = Bits32 (opcode, 10, 8);
2375                setflags = !InITBlock();
2376                imm32 = Bits32 (opcode, 7, 0);
2377
2378                break;
2379
2380            case eEncodingT3:
2381                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2382                // if Rn == '1101' then SEE ADD (SP plus immediate);
2383                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2384                d = Bits32 (opcode, 11, 8);
2385                n = Bits32 (opcode, 19, 16);
2386                setflags = BitIsSet (opcode, 20);
2387                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2388
2389                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2390                if (BadReg (d) || (n == 15))
2391                    return false;
2392
2393                break;
2394
2395            case eEncodingT4:
2396            {
2397                // if Rn == '1111' then SEE ADR;
2398                // if Rn == '1101' then SEE ADD (SP plus immediate);
2399                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2400                d = Bits32 (opcode, 11, 8);
2401                n = Bits32 (opcode, 19, 16);
2402                setflags = false;
2403                uint32_t i = Bit32 (opcode, 26);
2404                uint32_t imm3 = Bits32 (opcode, 14, 12);
2405                uint32_t imm8 = Bits32 (opcode, 7, 0);
2406                imm32 = (i << 11) | (imm3 << 8) | imm8;
2407
2408                // if BadReg(d) then UNPREDICTABLE;
2409                if (BadReg (d))
2410                    return false;
2411
2412                break;
2413            }
2414            default:
2415                return false;
2416        }
2417
2418        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2419        if (!success)
2420            return false;
2421
2422        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2423        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2424
2425        Register reg_n;
2426        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2427
2428        EmulateInstruction::Context context;
2429        context.type = eContextAddition;
2430        context.SetRegisterPlusOffset (reg_n, imm32);
2431
2432        //R[d] = result;
2433        //if setflags then
2434            //APSR.N = result<31>;
2435            //APSR.Z = IsZeroBit(result);
2436            //APSR.C = carry;
2437            //APSR.V = overflow;
2438        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2439            return false;
2440
2441    }
2442    return true;
2443}
2444
2445// This instruction adds an immediate value to a register value, and writes the result to the destination
2446// register.  It can optionally update the condition flags based on the result.
2447bool
2448EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2449{
2450#if 0
2451    // ARM pseudo code...
2452    if ConditionPassed() then
2453        EncodingSpecificOperations();
2454        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2455        if d == 15 then
2456            ALUWritePC(result); // setflags is always FALSE here
2457        else
2458            R[d] = result;
2459            if setflags then
2460                APSR.N = result<31>;
2461                APSR.Z = IsZeroBit(result);
2462                APSR.C = carry;
2463                APSR.V = overflow;
2464#endif
2465
2466    bool success = false;
2467
2468    if (ConditionPassed(opcode))
2469    {
2470        uint32_t Rd, Rn;
2471        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2472        bool setflags;
2473        switch (encoding)
2474        {
2475        case eEncodingA1:
2476            Rd = Bits32(opcode, 15, 12);
2477            Rn = Bits32(opcode, 19, 16);
2478            setflags = BitIsSet(opcode, 20);
2479            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2480            break;
2481        default:
2482            return false;
2483        }
2484
2485        // Read the first operand.
2486        uint32_t val1 = ReadCoreReg(Rn, &success);
2487        if (!success)
2488            return false;
2489
2490        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2491
2492        EmulateInstruction::Context context;
2493        context.type = EmulateInstruction::eContextAddition;
2494        Register dwarf_reg;
2495        dwarf_reg.SetRegister (eRegisterKindDWARF, Rn);
2496        context.SetRegisterPlusOffset (dwarf_reg, imm32);
2497
2498        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2499            return false;
2500    }
2501    return true;
2502}
2503
2504// This instruction adds a register value and an optionally-shifted register value, and writes the result
2505// to the destination register. It can optionally update the condition flags based on the result.
2506bool
2507EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2508{
2509#if 0
2510    // ARM pseudo code...
2511    if ConditionPassed() then
2512        EncodingSpecificOperations();
2513        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2514        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2515        if d == 15 then
2516            ALUWritePC(result); // setflags is always FALSE here
2517        else
2518            R[d] = result;
2519            if setflags then
2520                APSR.N = result<31>;
2521                APSR.Z = IsZeroBit(result);
2522                APSR.C = carry;
2523                APSR.V = overflow;
2524#endif
2525
2526    bool success = false;
2527
2528    if (ConditionPassed(opcode))
2529    {
2530        uint32_t Rd, Rn, Rm;
2531        ARM_ShifterType shift_t;
2532        uint32_t shift_n; // the shift applied to the value read from Rm
2533        bool setflags;
2534        switch (encoding)
2535        {
2536        case eEncodingT1:
2537            Rd = Bits32(opcode, 2, 0);
2538            Rn = Bits32(opcode, 5, 3);
2539            Rm = Bits32(opcode, 8, 6);
2540            setflags = !InITBlock();
2541            shift_t = SRType_LSL;
2542            shift_n = 0;
2543            break;
2544        case eEncodingT2:
2545            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2546            Rm = Bits32(opcode, 6, 3);
2547            setflags = false;
2548            shift_t = SRType_LSL;
2549            shift_n = 0;
2550            if (Rn == 15 && Rm == 15)
2551                return false;
2552            if (Rd == 15 && InITBlock() && !LastInITBlock())
2553                return false;
2554            break;
2555        case eEncodingA1:
2556            Rd = Bits32(opcode, 15, 12);
2557            Rn = Bits32(opcode, 19, 16);
2558            Rm = Bits32(opcode, 3, 0);
2559            setflags = BitIsSet(opcode, 20);
2560            shift_n = DecodeImmShiftARM(opcode, shift_t);
2561            break;
2562        default:
2563            return false;
2564        }
2565
2566        // Read the first operand.
2567        uint32_t val1 = ReadCoreReg(Rn, &success);
2568        if (!success)
2569            return false;
2570
2571        // Read the second operand.
2572        uint32_t val2 = ReadCoreReg(Rm, &success);
2573        if (!success)
2574            return false;
2575
2576        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2577        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2578
2579        EmulateInstruction::Context context;
2580        context.type = EmulateInstruction::eContextAddition;
2581        Register op1_reg;
2582        Register op2_reg;
2583        op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
2584        op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
2585        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2586
2587        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2588            return false;
2589    }
2590    return true;
2591}
2592
2593// Compare Negative (immediate) adds a register value and an immediate value.
2594// It updates the condition flags based on the result, and discards the result.
2595bool
2596EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2597{
2598#if 0
2599    // ARM pseudo code...
2600    if ConditionPassed() then
2601        EncodingSpecificOperations();
2602        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2603        APSR.N = result<31>;
2604        APSR.Z = IsZeroBit(result);
2605        APSR.C = carry;
2606        APSR.V = overflow;
2607#endif
2608
2609    bool success = false;
2610
2611    uint32_t Rn; // the first operand
2612    uint32_t imm32; // the immediate value to be compared with
2613    switch (encoding) {
2614    case eEncodingT1:
2615        Rn = Bits32(opcode, 19, 16);
2616        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2617        if (Rn == 15)
2618            return false;
2619        break;
2620    case eEncodingA1:
2621        Rn = Bits32(opcode, 19, 16);
2622        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2623        break;
2624    default:
2625        return false;
2626    }
2627    // Read the register value from the operand register Rn.
2628    uint32_t reg_val = ReadCoreReg(Rn, &success);
2629    if (!success)
2630        return false;
2631
2632    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2633
2634    EmulateInstruction::Context context;
2635    context.type = EmulateInstruction::eContextImmediate;
2636    context.SetNoArgs ();
2637    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2638        return false;
2639
2640    return true;
2641}
2642
2643// Compare Negative (register) adds a register value and an optionally-shifted register value.
2644// It updates the condition flags based on the result, and discards the result.
2645bool
2646EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2647{
2648#if 0
2649    // ARM pseudo code...
2650    if ConditionPassed() then
2651        EncodingSpecificOperations();
2652        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2653        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2654        APSR.N = result<31>;
2655        APSR.Z = IsZeroBit(result);
2656        APSR.C = carry;
2657        APSR.V = overflow;
2658#endif
2659
2660    bool success = false;
2661
2662    uint32_t Rn; // the first operand
2663    uint32_t Rm; // the second operand
2664    ARM_ShifterType shift_t;
2665    uint32_t shift_n; // the shift applied to the value read from Rm
2666    switch (encoding) {
2667    case eEncodingT1:
2668        Rn = Bits32(opcode, 2, 0);
2669        Rm = Bits32(opcode, 5, 3);
2670        shift_t = SRType_LSL;
2671        shift_n = 0;
2672        break;
2673    case eEncodingT2:
2674        Rn = Bits32(opcode, 19, 16);
2675        Rm = Bits32(opcode, 3, 0);
2676        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2677        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2678        if (Rn == 15 || BadReg(Rm))
2679            return false;
2680        break;
2681    case eEncodingA1:
2682        Rn = Bits32(opcode, 19, 16);
2683        Rm = Bits32(opcode, 3, 0);
2684        shift_n = DecodeImmShiftARM(opcode, shift_t);
2685        break;
2686    default:
2687        return false;
2688    }
2689    // Read the register value from register Rn.
2690    uint32_t val1 = ReadCoreReg(Rn, &success);
2691    if (!success)
2692        return false;
2693
2694    // Read the register value from register Rm.
2695    uint32_t val2 = ReadCoreReg(Rm, &success);
2696    if (!success)
2697        return false;
2698
2699    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2700    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2701
2702    EmulateInstruction::Context context;
2703    context.type = EmulateInstruction::eContextImmediate;
2704    context.SetNoArgs();
2705    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2706        return false;
2707
2708    return true;
2709}
2710
2711// Compare (immediate) subtracts an immediate value from a register value.
2712// It updates the condition flags based on the result, and discards the result.
2713bool
2714EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2715{
2716#if 0
2717    // ARM pseudo code...
2718    if ConditionPassed() then
2719        EncodingSpecificOperations();
2720        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2721        APSR.N = result<31>;
2722        APSR.Z = IsZeroBit(result);
2723        APSR.C = carry;
2724        APSR.V = overflow;
2725#endif
2726
2727    bool success = false;
2728
2729    uint32_t Rn; // the first operand
2730    uint32_t imm32; // the immediate value to be compared with
2731    switch (encoding) {
2732    case eEncodingT1:
2733        Rn = Bits32(opcode, 10, 8);
2734        imm32 = Bits32(opcode, 7, 0);
2735        break;
2736    case eEncodingT2:
2737        Rn = Bits32(opcode, 19, 16);
2738        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2739        if (Rn == 15)
2740            return false;
2741        break;
2742    case eEncodingA1:
2743        Rn = Bits32(opcode, 19, 16);
2744        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2745        break;
2746    default:
2747        return false;
2748    }
2749    // Read the register value from the operand register Rn.
2750    uint32_t reg_val = ReadCoreReg(Rn, &success);
2751    if (!success)
2752        return false;
2753
2754    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2755
2756    EmulateInstruction::Context context;
2757    context.type = EmulateInstruction::eContextImmediate;
2758    context.SetNoArgs ();
2759    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2760        return false;
2761
2762    return true;
2763}
2764
2765// Compare (register) subtracts an optionally-shifted register value from a register value.
2766// It updates the condition flags based on the result, and discards the result.
2767bool
2768EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2769{
2770#if 0
2771    // ARM pseudo code...
2772    if ConditionPassed() then
2773        EncodingSpecificOperations();
2774        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2775        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2776        APSR.N = result<31>;
2777        APSR.Z = IsZeroBit(result);
2778        APSR.C = carry;
2779        APSR.V = overflow;
2780#endif
2781
2782    bool success = false;
2783
2784    uint32_t Rn; // the first operand
2785    uint32_t Rm; // the second operand
2786    ARM_ShifterType shift_t;
2787    uint32_t shift_n; // the shift applied to the value read from Rm
2788    switch (encoding) {
2789    case eEncodingT1:
2790        Rn = Bits32(opcode, 2, 0);
2791        Rm = Bits32(opcode, 5, 3);
2792        shift_t = SRType_LSL;
2793        shift_n = 0;
2794        break;
2795    case eEncodingT2:
2796        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2797        Rm = Bits32(opcode, 6, 3);
2798        shift_t = SRType_LSL;
2799        shift_n = 0;
2800        if (Rn < 8 && Rm < 8)
2801            return false;
2802        if (Rn == 15 || Rm == 15)
2803            return false;
2804        break;
2805    case eEncodingA1:
2806        Rn = Bits32(opcode, 19, 16);
2807        Rm = Bits32(opcode, 3, 0);
2808        shift_n = DecodeImmShiftARM(opcode, shift_t);
2809        break;
2810    default:
2811        return false;
2812    }
2813    // Read the register value from register Rn.
2814    uint32_t val1 = ReadCoreReg(Rn, &success);
2815    if (!success)
2816        return false;
2817
2818    // Read the register value from register Rm.
2819    uint32_t val2 = ReadCoreReg(Rm, &success);
2820    if (!success)
2821        return false;
2822
2823    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2824    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2825
2826    EmulateInstruction::Context context;
2827    context.type = EmulateInstruction::eContextImmediate;
2828    context.SetNoArgs();
2829    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2830        return false;
2831
2832    return true;
2833}
2834
2835// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2836// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2837// optionally update the condition flags based on the result.
2838bool
2839EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2840{
2841#if 0
2842    // ARM pseudo code...
2843    if ConditionPassed() then
2844        EncodingSpecificOperations();
2845        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2846        if d == 15 then         // Can only occur for ARM encoding
2847            ALUWritePC(result); // setflags is always FALSE here
2848        else
2849            R[d] = result;
2850            if setflags then
2851                APSR.N = result<31>;
2852                APSR.Z = IsZeroBit(result);
2853                APSR.C = carry;
2854                // APSR.V unchanged
2855#endif
2856
2857    return EmulateShiftImm (opcode, encoding, SRType_ASR);
2858}
2859
2860// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2861// shifting in copies of its sign bit, and writes the result to the destination register.
2862// The variable number of bits is read from the bottom byte of a register. It can optionally update
2863// the condition flags based on the result.
2864bool
2865EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2866{
2867#if 0
2868    // ARM pseudo code...
2869    if ConditionPassed() then
2870        EncodingSpecificOperations();
2871        shift_n = UInt(R[m]<7:0>);
2872        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2873        R[d] = result;
2874        if setflags then
2875            APSR.N = result<31>;
2876            APSR.Z = IsZeroBit(result);
2877            APSR.C = carry;
2878            // APSR.V unchanged
2879#endif
2880
2881    return EmulateShiftReg (opcode, encoding, SRType_ASR);
2882}
2883
2884// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2885// shifting in zeros, and writes the result to the destination register.  It can optionally
2886// update the condition flags based on the result.
2887bool
2888EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2889{
2890#if 0
2891    // ARM pseudo code...
2892    if ConditionPassed() then
2893        EncodingSpecificOperations();
2894        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2895        if d == 15 then         // Can only occur for ARM encoding
2896            ALUWritePC(result); // setflags is always FALSE here
2897        else
2898            R[d] = result;
2899            if setflags then
2900                APSR.N = result<31>;
2901                APSR.Z = IsZeroBit(result);
2902                APSR.C = carry;
2903                // APSR.V unchanged
2904#endif
2905
2906    return EmulateShiftImm (opcode, encoding, SRType_LSL);
2907}
2908
2909// Logical Shift Left (register) shifts a register value left by a variable number of bits,
2910// shifting in zeros, and writes the result to the destination register.  The variable number
2911// of bits is read from the bottom byte of a register. It can optionally update the condition
2912// flags based on the result.
2913bool
2914EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
2915{
2916#if 0
2917    // ARM pseudo code...
2918    if ConditionPassed() then
2919        EncodingSpecificOperations();
2920        shift_n = UInt(R[m]<7:0>);
2921        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2922        R[d] = result;
2923        if setflags then
2924            APSR.N = result<31>;
2925            APSR.Z = IsZeroBit(result);
2926            APSR.C = carry;
2927            // APSR.V unchanged
2928#endif
2929
2930    return EmulateShiftReg (opcode, encoding, SRType_LSL);
2931}
2932
2933// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
2934// shifting in zeros, and writes the result to the destination register.  It can optionally
2935// update the condition flags based on the result.
2936bool
2937EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
2938{
2939#if 0
2940    // ARM pseudo code...
2941    if ConditionPassed() then
2942        EncodingSpecificOperations();
2943        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2944        if d == 15 then         // Can only occur for ARM encoding
2945            ALUWritePC(result); // setflags is always FALSE here
2946        else
2947            R[d] = result;
2948            if setflags then
2949                APSR.N = result<31>;
2950                APSR.Z = IsZeroBit(result);
2951                APSR.C = carry;
2952                // APSR.V unchanged
2953#endif
2954
2955    return EmulateShiftImm (opcode, encoding, SRType_LSR);
2956}
2957
2958// Logical Shift Right (register) shifts a register value right by a variable number of bits,
2959// shifting in zeros, and writes the result to the destination register.  The variable number
2960// of bits is read from the bottom byte of a register. It can optionally update the condition
2961// flags based on the result.
2962bool
2963EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
2964{
2965#if 0
2966    // ARM pseudo code...
2967    if ConditionPassed() then
2968        EncodingSpecificOperations();
2969        shift_n = UInt(R[m]<7:0>);
2970        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2971        R[d] = result;
2972        if setflags then
2973            APSR.N = result<31>;
2974            APSR.Z = IsZeroBit(result);
2975            APSR.C = carry;
2976            // APSR.V unchanged
2977#endif
2978
2979    return EmulateShiftReg (opcode, encoding, SRType_LSR);
2980}
2981
2982// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2983// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2984// It can optionally update the condition flags based on the result.
2985bool
2986EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
2987{
2988#if 0
2989    // ARM pseudo code...
2990    if ConditionPassed() then
2991        EncodingSpecificOperations();
2992        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2993        if d == 15 then         // Can only occur for ARM encoding
2994            ALUWritePC(result); // setflags is always FALSE here
2995        else
2996            R[d] = result;
2997            if setflags then
2998                APSR.N = result<31>;
2999                APSR.Z = IsZeroBit(result);
3000                APSR.C = carry;
3001                // APSR.V unchanged
3002#endif
3003
3004    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3005}
3006
3007// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3008// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3009// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3010// flags based on the result.
3011bool
3012EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3013{
3014#if 0
3015    // ARM pseudo code...
3016    if ConditionPassed() then
3017        EncodingSpecificOperations();
3018        shift_n = UInt(R[m]<7:0>);
3019        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3020        R[d] = result;
3021        if setflags then
3022            APSR.N = result<31>;
3023            APSR.Z = IsZeroBit(result);
3024            APSR.C = carry;
3025            // APSR.V unchanged
3026#endif
3027
3028    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3029}
3030
3031// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3032// with the carry flag shifted into bit [31].
3033//
3034// RRX can optionally update the condition flags based on the result.
3035// In that case, bit [0] is shifted into the carry flag.
3036bool
3037EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3038{
3039#if 0
3040    // ARM pseudo code...
3041    if ConditionPassed() then
3042        EncodingSpecificOperations();
3043        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3044        if d == 15 then         // Can only occur for ARM encoding
3045            ALUWritePC(result); // setflags is always FALSE here
3046        else
3047            R[d] = result;
3048            if setflags then
3049                APSR.N = result<31>;
3050                APSR.Z = IsZeroBit(result);
3051                APSR.C = carry;
3052                // APSR.V unchanged
3053#endif
3054
3055    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3056}
3057
3058bool
3059EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3060{
3061    assert(shift_type == SRType_ASR
3062           || shift_type == SRType_LSL
3063           || shift_type == SRType_LSR
3064           || shift_type == SRType_ROR
3065           || shift_type == SRType_RRX);
3066
3067    bool success = false;
3068
3069    if (ConditionPassed(opcode))
3070    {
3071        uint32_t Rd;    // the destination register
3072        uint32_t Rm;    // the first operand register
3073        uint32_t imm5;  // encoding for the shift amount
3074        uint32_t carry; // the carry bit after the shift operation
3075        bool setflags;
3076
3077        // Special case handling!
3078        // A8.6.139 ROR (immediate) -- Encoding T1
3079        ARMEncoding use_encoding = encoding;
3080        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3081        {
3082            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3083            // have the same decoding of bit fields as the other Thumb2 shift operations.
3084            use_encoding = eEncodingT2;
3085        }
3086
3087        switch (use_encoding) {
3088        case eEncodingT1:
3089            // Due to the above special case handling!
3090            assert(shift_type != SRType_ROR);
3091
3092            Rd = Bits32(opcode, 2, 0);
3093            Rm = Bits32(opcode, 5, 3);
3094            setflags = !InITBlock();
3095            imm5 = Bits32(opcode, 10, 6);
3096            break;
3097        case eEncodingT2:
3098            // A8.6.141 RRX
3099            assert(shift_type != SRType_RRX);
3100
3101            Rd = Bits32(opcode, 11, 8);
3102            Rm = Bits32(opcode, 3, 0);
3103            setflags = BitIsSet(opcode, 20);
3104            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3105            if (BadReg(Rd) || BadReg(Rm))
3106                return false;
3107            break;
3108        case eEncodingA1:
3109            Rd = Bits32(opcode, 15, 12);
3110            Rm = Bits32(opcode, 3, 0);
3111            setflags = BitIsSet(opcode, 20);
3112            imm5 = Bits32(opcode, 11, 7);
3113            break;
3114        default:
3115            return false;
3116        }
3117
3118        // A8.6.139 ROR (immediate)
3119        if (shift_type == SRType_ROR && imm5 == 0)
3120            shift_type = SRType_RRX;
3121
3122        // Get the first operand.
3123        uint32_t value = ReadCoreReg (Rm, &success);
3124        if (!success)
3125            return false;
3126
3127        // Decode the shift amount if not RRX.
3128        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3129
3130        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3131
3132        // The context specifies that an immediate is to be moved into Rd.
3133        EmulateInstruction::Context context;
3134        context.type = EmulateInstruction::eContextImmediate;
3135        context.SetNoArgs ();
3136
3137        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3138            return false;
3139    }
3140    return true;
3141}
3142
3143bool
3144EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3145{
3146    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
3147
3148    bool success = false;
3149
3150    if (ConditionPassed(opcode))
3151    {
3152        uint32_t Rd;    // the destination register
3153        uint32_t Rn;    // the first operand register
3154        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3155        uint32_t carry; // the carry bit after the shift operation
3156        bool setflags;
3157        switch (encoding) {
3158        case eEncodingT1:
3159            Rd = Bits32(opcode, 2, 0);
3160            Rn = Rd;
3161            Rm = Bits32(opcode, 5, 3);
3162            setflags = !InITBlock();
3163            break;
3164        case eEncodingT2:
3165            Rd = Bits32(opcode, 11, 8);
3166            Rn = Bits32(opcode, 19, 16);
3167            Rm = Bits32(opcode, 3, 0);
3168            setflags = BitIsSet(opcode, 20);
3169            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3170                return false;
3171            break;
3172        case eEncodingA1:
3173            Rd = Bits32(opcode, 15, 12);
3174            Rn = Bits32(opcode, 3, 0);
3175            Rm = Bits32(opcode, 11, 8);
3176            setflags = BitIsSet(opcode, 20);
3177            if (Rd == 15 || Rn == 15 || Rm == 15)
3178                return false;
3179            break;
3180        default:
3181            return false;
3182        }
3183
3184        // Get the first operand.
3185        uint32_t value = ReadCoreReg (Rn, &success);
3186        if (!success)
3187            return false;
3188        // Get the Rm register content.
3189        uint32_t val = ReadCoreReg (Rm, &success);
3190        if (!success)
3191            return false;
3192
3193        // Get the shift amount.
3194        uint32_t amt = Bits32(val, 7, 0);
3195
3196        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3197
3198        // The context specifies that an immediate is to be moved into Rd.
3199        EmulateInstruction::Context context;
3200        context.type = EmulateInstruction::eContextImmediate;
3201        context.SetNoArgs ();
3202
3203        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3204            return false;
3205    }
3206    return true;
3207}
3208
3209// LDM loads multiple registers from consecutive memory locations, using an
3210// address from a base register.  Optionally the address just above the highest of those locations
3211// can be written back to the base register.
3212bool
3213EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3214{
3215#if 0
3216    // ARM pseudo code...
3217    if ConditionPassed()
3218        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3219        address = R[n];
3220
3221        for i = 0 to 14
3222            if registers<i> == '1' then
3223                R[i] = MemA[address, 4]; address = address + 4;
3224        if registers<15> == '1' then
3225            LoadWritePC (MemA[address, 4]);
3226
3227        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3228        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3229
3230#endif
3231
3232    bool success = false;
3233
3234    if (ConditionPassed(opcode))
3235    {
3236        uint32_t n;
3237        uint32_t registers = 0;
3238        bool wback;
3239        const uint32_t addr_byte_size = GetAddressByteSize();
3240        switch (encoding)
3241        {
3242            case eEncodingT1:
3243                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3244                n = Bits32 (opcode, 10, 8);
3245                registers = Bits32 (opcode, 7, 0);
3246                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3247                wback = BitIsClear (registers, n);
3248                // if BitCount(registers) < 1 then UNPREDICTABLE;
3249                if (BitCount(registers) < 1)
3250                    return false;
3251                break;
3252            case eEncodingT2:
3253                // if W == '1' && Rn == '1101' then SEE POP;
3254                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3255                n = Bits32 (opcode, 19, 16);
3256                registers = Bits32 (opcode, 15, 0);
3257                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3258                wback = BitIsSet (opcode, 21);
3259
3260                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3261                if ((n == 15)
3262                    || (BitCount (registers) < 2)
3263                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3264                    return false;
3265
3266                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3267                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3268                    return false;
3269
3270                // if wback && registers<n> == '1' then UNPREDICTABLE;
3271                if (wback
3272                    && BitIsSet (registers, n))
3273                    return false;
3274                break;
3275
3276            case eEncodingA1:
3277                n = Bits32 (opcode, 19, 16);
3278                registers = Bits32 (opcode, 15, 0);
3279                wback = BitIsSet (opcode, 21);
3280                if ((n == 15)
3281                    || (BitCount (registers) < 1))
3282                    return false;
3283                break;
3284            default:
3285                return false;
3286        }
3287
3288        int32_t offset = 0;
3289        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3290        if (!success)
3291            return false;
3292
3293        EmulateInstruction::Context context;
3294        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3295        Register dwarf_reg;
3296        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3297        context.SetRegisterPlusOffset (dwarf_reg, offset);
3298
3299        for (int i = 0; i < 14; ++i)
3300        {
3301            if (BitIsSet (registers, i))
3302            {
3303                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3304                context.SetRegisterPlusOffset (dwarf_reg, offset);
3305                if (wback && (n == 13)) // Pop Instruction
3306                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
3307
3308                // R[i] = MemA [address, 4]; address = address + 4;
3309                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3310                if (!success)
3311                    return false;
3312
3313                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3314                    return false;
3315
3316                offset += addr_byte_size;
3317            }
3318        }
3319
3320        if (BitIsSet (registers, 15))
3321        {
3322            //LoadWritePC (MemA [address, 4]);
3323            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3324            context.SetRegisterPlusOffset (dwarf_reg, offset);
3325            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3326            if (!success)
3327                return false;
3328            // In ARMv5T and above, this is an interworking branch.
3329            if (!LoadWritePC(context, data))
3330                return false;
3331        }
3332
3333        if (wback && BitIsClear (registers, n))
3334        {
3335            // R[n] = R[n] + 4 * BitCount (registers)
3336            int32_t offset = addr_byte_size * BitCount (registers);
3337            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3338            context.SetRegisterPlusOffset (dwarf_reg, offset);
3339
3340            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3341                return false;
3342        }
3343        if (wback && BitIsSet (registers, n))
3344            // R[n] bits(32) UNKNOWN;
3345            return WriteBits32Unknown (n);
3346    }
3347    return true;
3348}
3349
3350// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3351// The consecutive memory locations end at this address and the address just below the lowest of those locations
3352// can optionally be written back to the base register.
3353bool
3354EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3355{
3356#if 0
3357    // ARM pseudo code...
3358    if ConditionPassed() then
3359        EncodingSpecificOperations();
3360        address = R[n] - 4*BitCount(registers) + 4;
3361
3362        for i = 0 to 14
3363            if registers<i> == '1' then
3364                  R[i] = MemA[address,4]; address = address + 4;
3365
3366        if registers<15> == '1' then
3367            LoadWritePC(MemA[address,4]);
3368
3369        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3370        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3371#endif
3372
3373    bool success = false;
3374
3375    if (ConditionPassed(opcode))
3376    {
3377        uint32_t n;
3378        uint32_t registers = 0;
3379        bool wback;
3380        const uint32_t addr_byte_size = GetAddressByteSize();
3381
3382        // EncodingSpecificOperations();
3383        switch (encoding)
3384        {
3385            case eEncodingA1:
3386                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3387                n = Bits32 (opcode, 19, 16);
3388                registers = Bits32 (opcode, 15, 0);
3389                wback = BitIsSet (opcode, 21);
3390
3391                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3392                if ((n == 15) || (BitCount (registers) < 1))
3393                    return false;
3394
3395                break;
3396
3397            default:
3398                return false;
3399        }
3400        // address = R[n] - 4*BitCount(registers) + 4;
3401
3402        int32_t offset = 0;
3403        addr_t Rn = ReadCoreReg (n, &success);
3404
3405        if (!success)
3406            return false;
3407
3408        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3409
3410        EmulateInstruction::Context context;
3411        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3412        Register dwarf_reg;
3413        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3414        context.SetRegisterPlusOffset (dwarf_reg, offset);
3415
3416        // for i = 0 to 14
3417        for (int i = 0; i < 14; ++i)
3418        {
3419            // if registers<i> == '1' then
3420            if (BitIsSet (registers, i))
3421            {
3422                  // R[i] = MemA[address,4]; address = address + 4;
3423                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3424                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3425                  if (!success)
3426                      return false;
3427                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3428                      return false;
3429                  offset += addr_byte_size;
3430            }
3431        }
3432
3433        // if registers<15> == '1' then
3434        //     LoadWritePC(MemA[address,4]);
3435        if (BitIsSet (registers, 15))
3436        {
3437            context.SetRegisterPlusOffset (dwarf_reg, offset);
3438            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3439            if (!success)
3440                return false;
3441            // In ARMv5T and above, this is an interworking branch.
3442            if (!LoadWritePC(context, data))
3443                return false;
3444        }
3445
3446        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3447        if (wback && BitIsClear (registers, n))
3448        {
3449            if (!success)
3450                return false;
3451
3452            offset = (addr_byte_size * BitCount (registers)) * -1;
3453            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3454            context.SetImmediateSigned (offset);
3455            addr_t addr = Rn + offset;
3456            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3457                return false;
3458        }
3459
3460        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3461        if (wback && BitIsSet (registers, n))
3462            return WriteBits32Unknown (n);
3463    }
3464    return true;
3465}
3466
3467// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3468// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3469// be optionally written back to the base register.
3470bool
3471EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3472{
3473#if 0
3474    // ARM pseudo code...
3475    if ConditionPassed() then
3476        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3477        address = R[n] - 4*BitCount(registers);
3478
3479        for i = 0 to 14
3480            if registers<i> == '1' then
3481                  R[i] = MemA[address,4]; address = address + 4;
3482        if registers<15> == '1' then
3483                  LoadWritePC(MemA[address,4]);
3484
3485        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3486        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3487#endif
3488
3489    bool success = false;
3490
3491    if (ConditionPassed(opcode))
3492    {
3493        uint32_t n;
3494        uint32_t registers = 0;
3495        bool wback;
3496        const uint32_t addr_byte_size = GetAddressByteSize();
3497        switch (encoding)
3498        {
3499            case eEncodingT1:
3500                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3501                n = Bits32 (opcode, 19, 16);
3502                registers = Bits32 (opcode, 15, 0);
3503                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3504                wback = BitIsSet (opcode, 21);
3505
3506                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3507                if ((n == 15)
3508                    || (BitCount (registers) < 2)
3509                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3510                    return false;
3511
3512                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3513                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3514                    return false;
3515
3516                // if wback && registers<n> == '1' then UNPREDICTABLE;
3517                if (wback && BitIsSet (registers, n))
3518                    return false;
3519
3520                break;
3521
3522            case eEncodingA1:
3523                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3524                n = Bits32 (opcode, 19, 16);
3525                registers = Bits32 (opcode, 15, 0);
3526                wback = BitIsSet (opcode, 21);
3527
3528                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3529                if ((n == 15) || (BitCount (registers) < 1))
3530                    return false;
3531
3532                break;
3533
3534            default:
3535                return false;
3536        }
3537
3538        // address = R[n] - 4*BitCount(registers);
3539
3540        int32_t offset = 0;
3541        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3542
3543        if (!success)
3544            return false;
3545
3546        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3547        EmulateInstruction::Context context;
3548        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3549        Register dwarf_reg;
3550        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3551        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3552
3553        for (int i = 0; i < 14; ++i)
3554        {
3555            if (BitIsSet (registers, i))
3556            {
3557                // R[i] = MemA[address,4]; address = address + 4;
3558                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3559                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3560                if (!success)
3561                    return false;
3562
3563                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3564                    return false;
3565
3566                offset += addr_byte_size;
3567            }
3568        }
3569
3570        // if registers<15> == '1' then
3571        //     LoadWritePC(MemA[address,4]);
3572        if (BitIsSet (registers, 15))
3573        {
3574            context.SetRegisterPlusOffset (dwarf_reg, offset);
3575            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3576            if (!success)
3577                return false;
3578            // In ARMv5T and above, this is an interworking branch.
3579            if (!LoadWritePC(context, data))
3580                return false;
3581        }
3582
3583        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3584        if (wback && BitIsClear (registers, n))
3585        {
3586            if (!success)
3587                return false;
3588
3589            offset = (addr_byte_size * BitCount (registers)) * -1;
3590            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3591            context.SetImmediateSigned (offset);
3592            addr_t addr = Rn + offset;
3593            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3594                return false;
3595        }
3596
3597        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3598        if (wback && BitIsSet (registers, n))
3599            return WriteBits32Unknown (n);
3600    }
3601    return true;
3602}
3603
3604// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3605// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3606// optinoally be written back to the base register.
3607bool
3608EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3609{
3610#if 0
3611    if ConditionPassed() then
3612        EncodingSpecificOperations();
3613        address = R[n] + 4;
3614
3615        for i = 0 to 14
3616            if registers<i> == '1' then
3617                  R[i] = MemA[address,4]; address = address + 4;
3618        if registers<15> == '1' then
3619            LoadWritePC(MemA[address,4]);
3620
3621        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3622        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3623#endif
3624
3625    bool success = false;
3626
3627    if (ConditionPassed(opcode))
3628    {
3629        uint32_t n;
3630        uint32_t registers = 0;
3631        bool wback;
3632        const uint32_t addr_byte_size = GetAddressByteSize();
3633        switch (encoding)
3634        {
3635            case eEncodingA1:
3636                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3637                n = Bits32 (opcode, 19, 16);
3638                registers = Bits32 (opcode, 15, 0);
3639                wback = BitIsSet (opcode, 21);
3640
3641                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3642                if ((n == 15) || (BitCount (registers) < 1))
3643                    return false;
3644
3645                break;
3646            default:
3647                return false;
3648        }
3649        // address = R[n] + 4;
3650
3651        int32_t offset = 0;
3652        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3653
3654        if (!success)
3655            return false;
3656
3657        addr_t address = Rn + addr_byte_size;
3658
3659        EmulateInstruction::Context context;
3660        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3661        Register dwarf_reg;
3662        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3663        context.SetRegisterPlusOffset (dwarf_reg, offset);
3664
3665        for (int i = 0; i < 14; ++i)
3666        {
3667            if (BitIsSet (registers, i))
3668            {
3669                // R[i] = MemA[address,4]; address = address + 4;
3670
3671                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3672                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3673                if (!success)
3674                    return false;
3675
3676                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3677                    return false;
3678
3679                offset += addr_byte_size;
3680            }
3681        }
3682
3683        // if registers<15> == '1' then
3684        //     LoadWritePC(MemA[address,4]);
3685        if (BitIsSet (registers, 15))
3686        {
3687            context.SetRegisterPlusOffset (dwarf_reg, offset);
3688            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3689            if (!success)
3690                return false;
3691            // In ARMv5T and above, this is an interworking branch.
3692            if (!LoadWritePC(context, data))
3693                return false;
3694        }
3695
3696        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3697        if (wback && BitIsClear (registers, n))
3698        {
3699            if (!success)
3700                return false;
3701
3702            offset = addr_byte_size * BitCount (registers);
3703            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3704            context.SetImmediateSigned (offset);
3705            addr_t addr = Rn + offset;
3706            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3707                return false;
3708        }
3709
3710        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3711        if (wback && BitIsSet (registers, n))
3712            return WriteBits32Unknown (n);
3713    }
3714    return true;
3715}
3716
3717// Load Register (immediate) calculates an address from a base register value and
3718// an immediate offset, loads a word from memory, and writes to a register.
3719// LDR (immediate, Thumb)
3720bool
3721EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3722{
3723#if 0
3724    // ARM pseudo code...
3725    if (ConditionPassed())
3726    {
3727        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3728        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3729        address = if index then offset_addr else R[n];
3730        data = MemU[address,4];
3731        if wback then R[n] = offset_addr;
3732        if t == 15 then
3733            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3734        elsif UnalignedSupport() || address<1:0> = '00' then
3735            R[t] = data;
3736        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3737    }
3738#endif
3739
3740    bool success = false;
3741
3742    if (ConditionPassed(opcode))
3743    {
3744        uint32_t Rt; // the destination register
3745        uint32_t Rn; // the base register
3746        uint32_t imm32; // the immediate offset used to form the address
3747        addr_t offset_addr; // the offset address
3748        addr_t address; // the calculated address
3749        uint32_t data; // the literal data value from memory load
3750        bool add, index, wback;
3751        switch (encoding) {
3752            case eEncodingT1:
3753                Rt = Bits32(opcode, 5, 3);
3754                Rn = Bits32(opcode, 2, 0);
3755                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3756                // index = TRUE; add = TRUE; wback = FALSE
3757                add = true;
3758                index = true;
3759                wback = false;
3760
3761                break;
3762
3763            case eEncodingT2:
3764                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3765                Rt = Bits32 (opcode, 10, 8);
3766                Rn = 13;
3767                imm32 = Bits32 (opcode, 7, 0) << 2;
3768
3769                // index = TRUE; add = TRUE; wback = FALSE;
3770                index = true;
3771                add = true;
3772                wback = false;
3773
3774                break;
3775
3776            case eEncodingT3:
3777                // if Rn == '1111' then SEE LDR (literal);
3778                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3779                Rt = Bits32 (opcode, 15, 12);
3780                Rn = Bits32 (opcode, 19, 16);
3781                imm32 = Bits32 (opcode, 11, 0);
3782
3783                // index = TRUE; add = TRUE; wback = FALSE;
3784                index = true;
3785                add = true;
3786                wback = false;
3787
3788                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3789                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3790                    return false;
3791
3792                break;
3793
3794            case eEncodingT4:
3795                // if Rn == '1111' then SEE LDR (literal);
3796                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3797                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3798                // if P == '0' && W == '0' then UNDEFINED;
3799                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3800                    return false;
3801
3802                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3803                Rt = Bits32 (opcode, 15, 12);
3804                Rn = Bits32 (opcode, 19, 16);
3805                imm32 = Bits32 (opcode, 7, 0);
3806
3807                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3808                index = BitIsSet (opcode, 10);
3809                add = BitIsSet (opcode, 9);
3810                wback = BitIsSet (opcode, 8);
3811
3812                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3813                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3814                    return false;
3815
3816                break;
3817
3818            default:
3819                return false;
3820        }
3821        uint32_t base = ReadCoreReg (Rn, &success);
3822        if (!success)
3823            return false;
3824        if (add)
3825            offset_addr = base + imm32;
3826        else
3827            offset_addr = base - imm32;
3828
3829        address = (index ? offset_addr : base);
3830
3831        Register base_reg;
3832        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
3833        if (wback)
3834        {
3835            EmulateInstruction::Context ctx;
3836            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3837            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3838
3839            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3840                return false;
3841        }
3842
3843        // Prepare to write to the Rt register.
3844        EmulateInstruction::Context context;
3845        context.type = EmulateInstruction::eContextRegisterLoad;
3846        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3847
3848        // Read memory from the address.
3849        data = MemURead(context, address, 4, 0, &success);
3850        if (!success)
3851            return false;
3852
3853        if (Rt == 15)
3854        {
3855            if (Bits32(address, 1, 0) == 0)
3856            {
3857                if (!LoadWritePC(context, data))
3858                    return false;
3859            }
3860            else
3861                return false;
3862        }
3863        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3864        {
3865            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3866                return false;
3867        }
3868        else
3869            WriteBits32Unknown (Rt);
3870    }
3871    return true;
3872}
3873
3874// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3875// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3876// of those locations can optionally be written back to the base register.
3877bool
3878EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3879{
3880#if 0
3881    if ConditionPassed() then
3882        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3883        address = R[n];
3884
3885        for i = 0 to 14
3886            if registers<i> == '1' then
3887                if i == n && wback && i != LowestSetBit(registers) then
3888                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3889                else
3890                    MemA[address,4] = R[i];
3891                address = address + 4;
3892
3893        if registers<15> == '1' then // Only possible for encoding A1
3894            MemA[address,4] = PCStoreValue();
3895        if wback then R[n] = R[n] + 4*BitCount(registers);
3896#endif
3897
3898    bool success = false;
3899
3900    if (ConditionPassed(opcode))
3901    {
3902        uint32_t n;
3903        uint32_t registers = 0;
3904        bool wback;
3905        const uint32_t addr_byte_size = GetAddressByteSize();
3906
3907        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3908        switch (encoding)
3909        {
3910            case eEncodingT1:
3911                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
3912                n = Bits32 (opcode, 10, 8);
3913                registers = Bits32 (opcode, 7, 0);
3914                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3915                wback = true;
3916
3917                // if BitCount(registers) < 1 then UNPREDICTABLE;
3918                if (BitCount (registers) < 1)
3919                    return false;
3920
3921                break;
3922
3923            case eEncodingT2:
3924                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
3925                n = Bits32 (opcode, 19, 16);
3926                registers = Bits32 (opcode, 15, 0);
3927                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3928                wback = BitIsSet (opcode, 21);
3929
3930                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3931                if ((n == 15) || (BitCount (registers) < 2))
3932                    return false;
3933
3934                // if wback && registers<n> == '1' then UNPREDICTABLE;
3935                if (wback && BitIsSet (registers, n))
3936                    return false;
3937
3938                break;
3939
3940            case eEncodingA1:
3941                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3942                n = Bits32 (opcode, 19, 16);
3943                registers = Bits32 (opcode, 15, 0);
3944                wback = BitIsSet (opcode, 21);
3945
3946                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3947                if ((n == 15) || (BitCount (registers) < 1))
3948                    return false;
3949
3950                break;
3951
3952            default:
3953                return false;
3954        }
3955
3956        // address = R[n];
3957        int32_t offset = 0;
3958        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3959        if (!success)
3960            return false;
3961
3962        EmulateInstruction::Context context;
3963        context.type = EmulateInstruction::eContextRegisterStore;
3964        Register base_reg;
3965        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3966
3967        // for i = 0 to 14
3968        int lowest_set_bit = 14;
3969        for (int i = 0; i < 14; ++i)
3970        {
3971            // if registers<i> == '1' then
3972            if (BitIsSet (registers, i))
3973            {
3974                  if (i < lowest_set_bit)
3975                      lowest_set_bit = i;
3976                  // if i == n && wback && i != LowestSetBit(registers) then
3977                  if ((i == n) && wback && (i != lowest_set_bit))
3978                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3979                      WriteBits32UnknownToMemory (address + offset);
3980                  else
3981                  {
3982                     // MemA[address,4] = R[i];
3983                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3984                      if (!success)
3985                          return false;
3986
3987                      Register data_reg;
3988                      data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3989                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3990                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
3991                          return false;
3992                  }
3993
3994                  // address = address + 4;
3995                  offset += addr_byte_size;
3996            }
3997        }
3998
3999        // if registers<15> == '1' then // Only possible for encoding A1
4000        //     MemA[address,4] = PCStoreValue();
4001        if (BitIsSet (registers, 15))
4002        {
4003            Register pc_reg;
4004            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4005            context.SetRegisterPlusOffset (pc_reg, 8);
4006            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4007            if (!success)
4008                return false;
4009
4010            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4011                return false;
4012        }
4013
4014        // if wback then R[n] = R[n] + 4*BitCount(registers);
4015        if (wback)
4016        {
4017            offset = addr_byte_size * BitCount (registers);
4018            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4019            context.SetImmediateSigned (offset);
4020            addr_t data = address + offset;
4021            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4022                return false;
4023        }
4024    }
4025    return true;
4026}
4027
4028// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4029// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4030// of those locations can optionally be written back to the base register.
4031bool
4032EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4033{
4034#if 0
4035    if ConditionPassed() then
4036        EncodingSpecificOperations();
4037        address = R[n] - 4*BitCount(registers) + 4;
4038
4039        for i = 0 to 14
4040            if registers<i> == '1' then
4041                if i == n && wback && i != LowestSetBit(registers) then
4042                    MemA[address,4] = bits(32) UNKNOWN;
4043                else
4044                    MemA[address,4] = R[i];
4045                address = address + 4;
4046
4047        if registers<15> == '1' then
4048            MemA[address,4] = PCStoreValue();
4049
4050        if wback then R[n] = R[n] - 4*BitCount(registers);
4051#endif
4052
4053    bool success = false;
4054
4055    if (ConditionPassed(opcode))
4056    {
4057        uint32_t n;
4058        uint32_t registers = 0;
4059        bool wback;
4060        const uint32_t addr_byte_size = GetAddressByteSize();
4061
4062        // EncodingSpecificOperations();
4063        switch (encoding)
4064        {
4065            case eEncodingA1:
4066                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4067                n = Bits32 (opcode, 19, 16);
4068                registers = Bits32 (opcode, 15, 0);
4069                wback = BitIsSet (opcode, 21);
4070
4071                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4072                if ((n == 15) || (BitCount (registers) < 1))
4073                    return false;
4074                break;
4075            default:
4076                return false;
4077        }
4078
4079        // address = R[n] - 4*BitCount(registers) + 4;
4080        int32_t offset = 0;
4081        addr_t Rn = ReadCoreReg (n, &success);
4082        if (!success)
4083            return false;
4084
4085        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4086
4087        EmulateInstruction::Context context;
4088        context.type = EmulateInstruction::eContextRegisterStore;
4089        Register base_reg;
4090        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4091
4092        // for i = 0 to 14
4093        int lowest_bit_set = 14;
4094        for (int i = 0; i < 14; ++i)
4095        {
4096            // if registers<i> == '1' then
4097            if (BitIsSet (registers, i))
4098            {
4099                if (i < lowest_bit_set)
4100                    lowest_bit_set = i;
4101                //if i == n && wback && i != LowestSetBit(registers) then
4102                if ((i == n) && wback && (i != lowest_bit_set))
4103                    // MemA[address,4] = bits(32) UNKNOWN;
4104                    WriteBits32UnknownToMemory (address + offset);
4105                else
4106                {
4107                    // MemA[address,4] = R[i];
4108                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4109                    if (!success)
4110                        return false;
4111
4112                    Register data_reg;
4113                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4114                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4115                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4116                        return false;
4117                }
4118
4119                // address = address + 4;
4120                offset += addr_byte_size;
4121            }
4122        }
4123
4124        // if registers<15> == '1' then
4125        //    MemA[address,4] = PCStoreValue();
4126        if (BitIsSet (registers, 15))
4127        {
4128            Register pc_reg;
4129            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4130            context.SetRegisterPlusOffset (pc_reg, 8);
4131            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4132            if (!success)
4133                return false;
4134
4135            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4136                return false;
4137        }
4138
4139        // if wback then R[n] = R[n] - 4*BitCount(registers);
4140        if (wback)
4141        {
4142            offset = (addr_byte_size * BitCount (registers)) * -1;
4143            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4144            context.SetImmediateSigned (offset);
4145            addr_t data = Rn + offset;
4146            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4147                return false;
4148        }
4149    }
4150    return true;
4151}
4152
4153// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4154// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4155// those locations can optionally be written back to the base register.
4156bool
4157EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4158{
4159#if 0
4160    if ConditionPassed() then
4161        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4162        address = R[n] - 4*BitCount(registers);
4163
4164        for i = 0 to 14
4165            if registers<i> == '1' then
4166                if i == n && wback && i != LowestSetBit(registers) then
4167                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4168                else
4169                    MemA[address,4] = R[i];
4170                address = address + 4;
4171
4172        if registers<15> == '1' then // Only possible for encoding A1
4173            MemA[address,4] = PCStoreValue();
4174
4175        if wback then R[n] = R[n] - 4*BitCount(registers);
4176#endif
4177
4178
4179    bool success = false;
4180
4181    if (ConditionPassed(opcode))
4182    {
4183        uint32_t n;
4184        uint32_t registers = 0;
4185        bool wback;
4186        const uint32_t addr_byte_size = GetAddressByteSize();
4187
4188        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4189        switch (encoding)
4190        {
4191            case eEncodingT1:
4192                // if W == '1' && Rn == '1101' then SEE PUSH;
4193                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4194                {
4195                    // See PUSH
4196                }
4197                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4198                n = Bits32 (opcode, 19, 16);
4199                registers = Bits32 (opcode, 15, 0);
4200                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4201                wback = BitIsSet (opcode, 21);
4202                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4203                if ((n == 15) || BitCount (registers) < 2)
4204                    return false;
4205                // if wback && registers<n> == '1' then UNPREDICTABLE;
4206                if (wback && BitIsSet (registers, n))
4207                    return false;
4208                break;
4209
4210            case eEncodingA1:
4211                // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH;
4212                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4213                {
4214                    // See Push
4215                }
4216                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4217                n = Bits32 (opcode, 19, 16);
4218                registers = Bits32 (opcode, 15, 0);
4219                wback = BitIsSet (opcode, 21);
4220                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4221                if ((n == 15) || BitCount (registers) < 1)
4222                    return false;
4223                break;
4224
4225            default:
4226                return false;
4227        }
4228
4229        // address = R[n] - 4*BitCount(registers);
4230
4231        int32_t offset = 0;
4232        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4233        if (!success)
4234        return false;
4235
4236        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4237
4238        EmulateInstruction::Context context;
4239        context.type = EmulateInstruction::eContextRegisterStore;
4240        Register base_reg;
4241        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4242
4243        // for i = 0 to 14
4244        uint32_t lowest_set_bit = 14;
4245        for (int i = 0; i < 14; ++i)
4246        {
4247            // if registers<i> == '1' then
4248            if (BitIsSet (registers, i))
4249            {
4250                if (i < lowest_set_bit)
4251                    lowest_set_bit = i;
4252                // if i == n && wback && i != LowestSetBit(registers) then
4253                if ((i == n) && wback && (i != lowest_set_bit))
4254                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4255                    WriteBits32UnknownToMemory (address + offset);
4256                else
4257                {
4258                    // MemA[address,4] = R[i];
4259                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4260                    if (!success)
4261                        return false;
4262
4263                    Register data_reg;
4264                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4265                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4266                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4267                        return false;
4268                }
4269
4270                // address = address + 4;
4271                offset += addr_byte_size;
4272            }
4273        }
4274
4275        // if registers<15> == '1' then // Only possible for encoding A1
4276        //     MemA[address,4] = PCStoreValue();
4277        if (BitIsSet (registers, 15))
4278        {
4279            Register pc_reg;
4280            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4281            context.SetRegisterPlusOffset (pc_reg, 8);
4282            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4283            if (!success)
4284                return false;
4285
4286            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4287                return false;
4288        }
4289
4290        // if wback then R[n] = R[n] - 4*BitCount(registers);
4291        if (wback)
4292        {
4293            offset = (addr_byte_size * BitCount (registers)) * -1;
4294            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4295            context.SetImmediateSigned (offset);
4296            addr_t data = Rn + offset;
4297            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4298                return false;
4299        }
4300    }
4301    return true;
4302}
4303
4304// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4305// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4306// of those locations can optionally be written back to the base register.
4307bool
4308EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4309{
4310#if 0
4311    if ConditionPassed() then
4312        EncodingSpecificOperations();
4313        address = R[n] + 4;
4314
4315        for i = 0 to 14
4316            if registers<i> == '1' then
4317                if i == n && wback && i != LowestSetBit(registers) then
4318                    MemA[address,4] = bits(32) UNKNOWN;
4319                else
4320                    MemA[address,4] = R[i];
4321                address = address + 4;
4322
4323        if registers<15> == '1' then
4324            MemA[address,4] = PCStoreValue();
4325
4326        if wback then R[n] = R[n] + 4*BitCount(registers);
4327#endif
4328
4329    bool success = false;
4330
4331    if (ConditionPassed(opcode))
4332    {
4333        uint32_t n;
4334        uint32_t registers = 0;
4335        bool wback;
4336        const uint32_t addr_byte_size = GetAddressByteSize();
4337
4338        // EncodingSpecificOperations();
4339        switch (encoding)
4340        {
4341            case eEncodingA1:
4342                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4343                n = Bits32 (opcode, 19, 16);
4344                registers = Bits32 (opcode, 15, 0);
4345                wback = BitIsSet (opcode, 21);
4346
4347                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4348                if ((n == 15) && (BitCount (registers) < 1))
4349                    return false;
4350                break;
4351            default:
4352                return false;
4353        }
4354        // address = R[n] + 4;
4355
4356        int32_t offset = 0;
4357        addr_t Rn = ReadCoreReg (n, &success);
4358        if (!success)
4359            return false;
4360
4361        addr_t address = Rn + addr_byte_size;
4362
4363        EmulateInstruction::Context context;
4364        context.type = EmulateInstruction::eContextRegisterStore;
4365        Register base_reg;
4366        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4367
4368        uint32_t lowest_set_bit = 14;
4369        // for i = 0 to 14
4370        for (int i = 0; i < 14; ++i)
4371        {
4372            // if registers<i> == '1' then
4373            if (BitIsSet (registers, i))
4374            {
4375                if (i < lowest_set_bit)
4376                    lowest_set_bit = i;
4377                // if i == n && wback && i != LowestSetBit(registers) then
4378                if ((i == n) && wback && (i != lowest_set_bit))
4379                    // MemA[address,4] = bits(32) UNKNOWN;
4380                    WriteBits32UnknownToMemory (address + offset);
4381                // else
4382                else
4383                {
4384                    // MemA[address,4] = R[i];
4385                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4386                    if (!success)
4387                        return false;
4388
4389                    Register data_reg;
4390                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4391                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4392                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4393                        return false;
4394                }
4395
4396                // address = address + 4;
4397                offset += addr_byte_size;
4398            }
4399        }
4400
4401        // if registers<15> == '1' then
4402            // MemA[address,4] = PCStoreValue();
4403        if (BitIsSet (registers, 15))
4404        {
4405            Register pc_reg;
4406            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4407            context.SetRegisterPlusOffset (pc_reg, 8);
4408            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4409            if (!success)
4410            return false;
4411
4412            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4413                return false;
4414        }
4415
4416        // if wback then R[n] = R[n] + 4*BitCount(registers);
4417        if (wback)
4418        {
4419            offset = addr_byte_size * BitCount (registers);
4420            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4421            context.SetImmediateSigned (offset);
4422            addr_t data = Rn + offset;
4423            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4424                return false;
4425        }
4426    }
4427    return true;
4428}
4429
4430// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4431// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4432bool
4433EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4434{
4435#if 0
4436    if ConditionPassed() then
4437        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4438        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4439        address = if index then offset_addr else R[n];
4440        if UnalignedSupport() || address<1:0> == '00' then
4441            MemU[address,4] = R[t];
4442        else // Can only occur before ARMv7
4443            MemU[address,4] = bits(32) UNKNOWN;
4444        if wback then R[n] = offset_addr;
4445#endif
4446
4447    bool success = false;
4448
4449    if (ConditionPassed(opcode))
4450    {
4451        const uint32_t addr_byte_size = GetAddressByteSize();
4452
4453        uint32_t t;
4454        uint32_t n;
4455        uint32_t imm32;
4456        bool index;
4457        bool add;
4458        bool wback;
4459        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4460        switch (encoding)
4461        {
4462            case eEncodingT1:
4463                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4464                t = Bits32 (opcode, 2, 0);
4465                n = Bits32 (opcode, 5, 3);
4466                imm32 = Bits32 (opcode, 10, 6) << 2;
4467
4468                // index = TRUE; add = TRUE; wback = FALSE;
4469                index = true;
4470                add = false;
4471                wback = false;
4472                break;
4473
4474            case eEncodingT2:
4475                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4476                t = Bits32 (opcode, 10, 8);
4477                n = 13;
4478                imm32 = Bits32 (opcode, 7, 0) << 2;
4479
4480                // index = TRUE; add = TRUE; wback = FALSE;
4481                index = true;
4482                add = true;
4483                wback = false;
4484                break;
4485
4486            case eEncodingT3:
4487                // if Rn == '1111' then UNDEFINED;
4488                if (Bits32 (opcode, 19, 16) == 15)
4489                    return false;
4490
4491                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4492                t = Bits32 (opcode, 15, 12);
4493                n = Bits32 (opcode, 19, 16);
4494                imm32 = Bits32 (opcode, 11, 0);
4495
4496                // index = TRUE; add = TRUE; wback = FALSE;
4497                index = true;
4498                add = true;
4499                wback = false;
4500
4501                // if t == 15 then UNPREDICTABLE;
4502                if (t == 15)
4503                    return false;
4504                break;
4505
4506            case eEncodingT4:
4507                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4508                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4509                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4510                if ((Bits32 (opcode, 19, 16) == 15)
4511                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4512                    return false;
4513
4514                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4515                t = Bits32 (opcode, 15, 12);
4516                n = Bits32 (opcode, 19, 16);
4517                imm32 = Bits32 (opcode, 7, 0);
4518
4519                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4520                index = BitIsSet (opcode, 10);
4521                add = BitIsSet (opcode, 9);
4522                wback = BitIsSet (opcode, 8);
4523
4524                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4525                if ((t == 15) || (wback && (n == t)))
4526                    return false;
4527                break;
4528
4529            default:
4530                return false;
4531        }
4532
4533        addr_t offset_addr;
4534        addr_t address;
4535
4536        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4537        uint32_t base_address = ReadCoreReg (n, &success);
4538        if (!success)
4539            return false;
4540
4541        if (add)
4542            offset_addr = base_address + imm32;
4543        else
4544            offset_addr = base_address - imm32;
4545
4546        // address = if index then offset_addr else R[n];
4547        if (index)
4548            address = offset_addr;
4549        else
4550            address = base_address;
4551
4552        EmulateInstruction::Context context;
4553        context.type = eContextRegisterStore;
4554        Register base_reg;
4555        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4556
4557        // if UnalignedSupport() || address<1:0> == '00' then
4558        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4559        {
4560            // MemU[address,4] = R[t];
4561            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4562            if (!success)
4563                return false;
4564
4565            Register data_reg;
4566            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4567            int32_t offset = address - base_address;
4568            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4569            if (!MemUWrite (context, address, data, addr_byte_size))
4570                return false;
4571        }
4572        else
4573        {
4574            // MemU[address,4] = bits(32) UNKNOWN;
4575            WriteBits32UnknownToMemory (address);
4576        }
4577
4578        // if wback then R[n] = offset_addr;
4579        if (wback)
4580        {
4581            context.type = eContextRegisterLoad;
4582            context.SetAddress (offset_addr);
4583            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4584                return false;
4585        }
4586    }
4587    return true;
4588}
4589
4590// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4591// word from a register to memory.   The offset register value can optionally be shifted.
4592bool
4593EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4594{
4595#if 0
4596    if ConditionPassed() then
4597        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4598        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4599        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4600        address = if index then offset_addr else R[n];
4601        if t == 15 then // Only possible for encoding A1
4602            data = PCStoreValue();
4603        else
4604            data = R[t];
4605        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4606            MemU[address,4] = data;
4607        else // Can only occur before ARMv7
4608            MemU[address,4] = bits(32) UNKNOWN;
4609        if wback then R[n] = offset_addr;
4610#endif
4611
4612    bool success = false;
4613
4614    if (ConditionPassed(opcode))
4615    {
4616        const uint32_t addr_byte_size = GetAddressByteSize();
4617
4618        uint32_t t;
4619        uint32_t n;
4620        uint32_t m;
4621        ARM_ShifterType shift_t;
4622        uint32_t shift_n;
4623        bool index;
4624        bool add;
4625        bool wback;
4626
4627        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4628        switch (encoding)
4629        {
4630            case eEncodingT1:
4631                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4632                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4633                t = Bits32 (opcode, 2, 0);
4634                n = Bits32 (opcode, 5, 3);
4635                m = Bits32 (opcode, 8, 6);
4636
4637                // index = TRUE; add = TRUE; wback = FALSE;
4638                index = true;
4639                add = true;
4640                wback = false;
4641
4642                // (shift_t, shift_n) = (SRType_LSL, 0);
4643                shift_t = SRType_LSL;
4644                shift_n = 0;
4645                break;
4646
4647            case eEncodingT2:
4648                // if Rn == '1111' then UNDEFINED;
4649                if (Bits32 (opcode, 19, 16) == 15)
4650                    return false;
4651
4652                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4653                t = Bits32 (opcode, 15, 12);
4654                n = Bits32 (opcode, 19, 16);
4655                m = Bits32 (opcode, 3, 0);
4656
4657                // index = TRUE; add = TRUE; wback = FALSE;
4658                index = true;
4659                add = true;
4660                wback = false;
4661
4662                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4663                shift_t = SRType_LSL;
4664                shift_n = Bits32 (opcode, 5, 4);
4665
4666                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4667                if ((t == 15) || (BadReg (m)))
4668                    return false;
4669                break;
4670
4671            case eEncodingA1:
4672            {
4673                // if P == '0' && W == '1' then SEE STRT;
4674                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4675                t = Bits32 (opcode, 15, 12);
4676                n = Bits32 (opcode, 19, 16);
4677                m = Bits32 (opcode, 3, 0);
4678
4679                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4680                index = BitIsSet (opcode, 24);
4681                add = BitIsSet (opcode, 23);
4682                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4683
4684                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4685                uint32_t typ = Bits32 (opcode, 6, 5);
4686                uint32_t imm5 = Bits32 (opcode, 11, 7);
4687                shift_n = DecodeImmShift(typ, imm5, shift_t);
4688
4689                // if m == 15 then UNPREDICTABLE;
4690                if (m == 15)
4691                    return false;
4692
4693                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4694                if (wback && ((n == 15) || (n == t)))
4695                    return false;
4696
4697                break;
4698            }
4699            default:
4700                return false;
4701        }
4702
4703        addr_t offset_addr;
4704        addr_t address;
4705        int32_t offset = 0;
4706
4707        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4708        if (!success)
4709            return false;
4710
4711        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4712        if (!success)
4713            return false;
4714
4715        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4716        offset = Shift (Rm_data, shift_t, shift_n, APSR_C);
4717
4718        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4719        if (add)
4720            offset_addr = base_address + offset;
4721        else
4722            offset_addr = base_address - offset;
4723
4724        // address = if index then offset_addr else R[n];
4725        if (index)
4726            address = offset_addr;
4727        else
4728            address = base_address;
4729
4730        uint32_t data;
4731        // if t == 15 then // Only possible for encoding A1
4732        if (t == 15)
4733            // data = PCStoreValue();
4734            data = ReadCoreReg (PC_REG, &success);
4735        else
4736            // data = R[t];
4737            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4738
4739        if (!success)
4740            return false;
4741
4742        EmulateInstruction::Context context;
4743        context.type = eContextRegisterStore;
4744
4745        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4746        if (UnalignedSupport ()
4747            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4748            || CurrentInstrSet() == eModeARM)
4749        {
4750            // MemU[address,4] = data;
4751
4752            Register base_reg;
4753            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4754
4755            Register data_reg;
4756            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4757
4758            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4759            if (!MemUWrite (context, address, data, addr_byte_size))
4760                return false;
4761
4762        }
4763        else
4764            // MemU[address,4] = bits(32) UNKNOWN;
4765            WriteBits32UnknownToMemory (address);
4766
4767        // if wback then R[n] = offset_addr;
4768        if (wback)
4769        {
4770            context.type = eContextRegisterLoad;
4771            context.SetAddress (offset_addr);
4772            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4773                return false;
4774        }
4775
4776    }
4777    return true;
4778}
4779
4780bool
4781EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4782{
4783#if 0
4784    if ConditionPassed() then
4785        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4786        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4787        address = if index then offset_addr else R[n];
4788        MemU[address,1] = R[t]<7:0>;
4789        if wback then R[n] = offset_addr;
4790#endif
4791
4792
4793    bool success = false;
4794
4795    if (ConditionPassed(opcode))
4796    {
4797        uint32_t t;
4798        uint32_t n;
4799        uint32_t imm32;
4800        bool index;
4801        bool add;
4802        bool wback;
4803        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4804        switch (encoding)
4805        {
4806            case eEncodingT1:
4807                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4808                t = Bits32 (opcode, 2, 0);
4809                n = Bits32 (opcode, 5, 3);
4810                imm32 = Bits32 (opcode, 10, 6);
4811
4812                // index = TRUE; add = TRUE; wback = FALSE;
4813                index = true;
4814                add = true;
4815                wback = false;
4816                break;
4817
4818            case eEncodingT2:
4819                // if Rn == '1111' then UNDEFINED;
4820                if (Bits32 (opcode, 19, 16) == 15)
4821                    return false;
4822
4823                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4824                t = Bits32 (opcode, 15, 12);
4825                n = Bits32 (opcode, 19, 16);
4826                imm32 = Bits32 (opcode, 11, 0);
4827
4828                // index = TRUE; add = TRUE; wback = FALSE;
4829                index = true;
4830                add = true;
4831                wback = false;
4832
4833                // if BadReg(t) then UNPREDICTABLE;
4834                if (BadReg (t))
4835                    return false;
4836                break;
4837
4838            case eEncodingT3:
4839                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4840                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4841                if (Bits32 (opcode, 19, 16) == 15)
4842                    return false;
4843
4844                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4845                t = Bits32 (opcode, 15, 12);
4846                n = Bits32 (opcode, 19, 16);
4847                imm32 = Bits32 (opcode, 7, 0);
4848
4849                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4850                index = BitIsSet (opcode, 10);
4851                add = BitIsSet (opcode, 9);
4852                wback = BitIsSet (opcode, 8);
4853
4854                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4855                if ((BadReg (t)) || (wback && (n == t)))
4856                    return false;
4857                break;
4858
4859            default:
4860                return false;
4861        }
4862
4863        addr_t offset_addr;
4864        addr_t address;
4865        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4866        if (!success)
4867            return false;
4868
4869        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4870        if (add)
4871            offset_addr = base_address + imm32;
4872        else
4873            offset_addr = base_address - imm32;
4874
4875        // address = if index then offset_addr else R[n];
4876        if (index)
4877            address = offset_addr;
4878        else
4879            address = base_address;
4880
4881        // MemU[address,1] = R[t]<7:0>
4882        Register base_reg;
4883        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4884
4885        Register data_reg;
4886        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4887
4888        EmulateInstruction::Context context;
4889        context.type = eContextRegisterStore;
4890        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4891
4892        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4893        if (!success)
4894            return false;
4895
4896        data = Bits32 (data, 7, 0);
4897
4898        if (!MemUWrite (context, address, data, 1))
4899            return false;
4900
4901        // if wback then R[n] = offset_addr;
4902        if (wback)
4903        {
4904            context.type = eContextRegisterLoad;
4905            context.SetAddress (offset_addr);
4906            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4907                return false;
4908        }
4909
4910    }
4911
4912    return true;
4913}
4914
4915// STRH (register) calculates an address from a base register value and an offset register value, and stores a
4916// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
4917bool
4918EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
4919{
4920#if 0
4921    if ConditionPassed() then
4922        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4923        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4924        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4925        address = if index then offset_addr else R[n];
4926        if UnalignedSupport() || address<0> == '0' then
4927            MemU[address,2] = R[t]<15:0>;
4928        else // Can only occur before ARMv7
4929            MemU[address,2] = bits(16) UNKNOWN;
4930        if wback then R[n] = offset_addr;
4931#endif
4932
4933    bool success = false;
4934
4935    if (ConditionPassed(opcode))
4936    {
4937        uint32_t t;
4938        uint32_t n;
4939        uint32_t m;
4940        bool index;
4941        bool add;
4942        bool wback;
4943        ARM_ShifterType shift_t;
4944        uint32_t shift_n;
4945
4946        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4947        switch (encoding)
4948        {
4949            case eEncodingT1:
4950                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4951                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4952                t = Bits32 (opcode, 2, 0);
4953                n = Bits32 (opcode, 5, 3);
4954                m = Bits32 (opcode, 8, 6);
4955
4956                // index = TRUE; add = TRUE; wback = FALSE;
4957                index = true;
4958                add = true;
4959                wback = false;
4960
4961                // (shift_t, shift_n) = (SRType_LSL, 0);
4962                shift_t = SRType_LSL;
4963                shift_n = 0;
4964
4965                break;
4966
4967            case eEncodingT2:
4968                // if Rn == '1111' then UNDEFINED;
4969                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4970                t = Bits32 (opcode, 15, 12);
4971                n = Bits32 (opcode, 19, 16);
4972                m = Bits32 (opcode, 3, 0);
4973                if (n == 15)
4974                    return false;
4975
4976                // index = TRUE; add = TRUE; wback = FALSE;
4977                index = true;
4978                add = true;
4979                wback = false;
4980
4981                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4982                shift_t = SRType_LSL;
4983                shift_n = Bits32 (opcode, 5, 4);
4984
4985                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
4986                if (BadReg (t) || BadReg (m))
4987                    return false;
4988
4989                break;
4990
4991            case eEncodingA1:
4992                // if P == '0' && W == '1' then SEE STRHT;
4993                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4994                t = Bits32 (opcode, 15, 12);
4995                n = Bits32 (opcode, 19, 16);
4996                m = Bits32 (opcode, 3, 0);
4997
4998                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4999                index = BitIsSet (opcode, 24);
5000                add = BitIsSet (opcode, 23);
5001                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5002
5003                // (shift_t, shift_n) = (SRType_LSL, 0);
5004                shift_t = SRType_LSL;
5005                shift_n = 0;
5006
5007                // if t == 15 || m == 15 then UNPREDICTABLE;
5008                if ((t == 15) || (m == 15))
5009                    return false;
5010
5011                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5012                if (wback && ((n == 15) || (n == t)))
5013                    return false;
5014
5015                break;
5016
5017            default:
5018                return false;
5019        }
5020
5021        uint32_t Rm = ReadCoreReg (m, &success);
5022        if (!success)
5023            return false;
5024
5025        uint32_t Rn = ReadCoreReg (n, &success);
5026        if (!success)
5027            return false;
5028
5029        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5030        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
5031
5032        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5033        addr_t offset_addr;
5034        if (add)
5035            offset_addr = Rn + offset;
5036        else
5037            offset_addr = Rn - offset;
5038
5039        // address = if index then offset_addr else R[n];
5040        addr_t address;
5041        if (index)
5042            address = offset_addr;
5043        else
5044            address = Rn;
5045
5046        EmulateInstruction::Context context;
5047        context.type = eContextRegisterStore;
5048        Register base_reg;
5049        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5050        Register offset_reg;
5051        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5052
5053        // if UnalignedSupport() || address<0> == '0' then
5054        if (UnalignedSupport() || BitIsClear (address, 0))
5055        {
5056            // MemU[address,2] = R[t]<15:0>;
5057            uint32_t Rt = ReadCoreReg (t, &success);
5058            if (!success)
5059                return false;
5060
5061            EmulateInstruction::Context context;
5062            context.type = eContextRegisterStore;
5063            Register base_reg;
5064            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5065            Register offset_reg;
5066            offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5067            Register data_reg;
5068            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
5069            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5070
5071            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5072                return false;
5073        }
5074        else // Can only occur before ARMv7
5075        {
5076            // MemU[address,2] = bits(16) UNKNOWN;
5077        }
5078
5079        // if wback then R[n] = offset_addr;
5080        if (wback)
5081        {
5082            context.type = eContextAdjustBaseRegister;
5083            context.SetAddress (offset_addr);
5084            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5085                return false;
5086        }
5087    }
5088
5089    return true;
5090}
5091
5092// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5093// and writes the result to the destination register.  It can optionally update the condition flags
5094// based on the result.
5095bool
5096EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5097{
5098#if 0
5099    // ARM pseudo code...
5100    if ConditionPassed() then
5101        EncodingSpecificOperations();
5102        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5103        if d == 15 then         // Can only occur for ARM encoding
5104            ALUWritePC(result); // setflags is always FALSE here
5105        else
5106            R[d] = result;
5107            if setflags then
5108                APSR.N = result<31>;
5109                APSR.Z = IsZeroBit(result);
5110                APSR.C = carry;
5111                APSR.V = overflow;
5112#endif
5113
5114    bool success = false;
5115
5116    if (ConditionPassed(opcode))
5117    {
5118        uint32_t Rd, Rn;
5119        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5120        bool setflags;
5121        switch (encoding)
5122        {
5123        case eEncodingT1:
5124            Rd = Bits32(opcode, 11, 8);
5125            Rn = Bits32(opcode, 19, 16);
5126            setflags = BitIsSet(opcode, 20);
5127            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5128            if (BadReg(Rd) || BadReg(Rn))
5129                return false;
5130            break;
5131        case eEncodingA1:
5132            Rd = Bits32(opcode, 15, 12);
5133            Rn = Bits32(opcode, 19, 16);
5134            setflags = BitIsSet(opcode, 20);
5135            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5136
5137            if (Rd == 15 && setflags)
5138                return EmulateSUBSPcLrEtc (opcode, encoding);
5139            break;
5140        default:
5141            return false;
5142        }
5143
5144        // Read the first operand.
5145        int32_t val1 = ReadCoreReg(Rn, &success);
5146        if (!success)
5147            return false;
5148
5149        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5150
5151        EmulateInstruction::Context context;
5152        context.type = EmulateInstruction::eContextImmediate;
5153        context.SetNoArgs ();
5154
5155        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5156            return false;
5157    }
5158    return true;
5159}
5160
5161// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5162// register value, and writes the result to the destination register.  It can optionally update the
5163// condition flags based on the result.
5164bool
5165EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5166{
5167#if 0
5168    // ARM pseudo code...
5169    if ConditionPassed() then
5170        EncodingSpecificOperations();
5171        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5172        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5173        if d == 15 then         // Can only occur for ARM encoding
5174            ALUWritePC(result); // setflags is always FALSE here
5175        else
5176            R[d] = result;
5177            if setflags then
5178                APSR.N = result<31>;
5179                APSR.Z = IsZeroBit(result);
5180                APSR.C = carry;
5181                APSR.V = overflow;
5182#endif
5183
5184    bool success = false;
5185
5186    if (ConditionPassed(opcode))
5187    {
5188        uint32_t Rd, Rn, Rm;
5189        ARM_ShifterType shift_t;
5190        uint32_t shift_n; // the shift applied to the value read from Rm
5191        bool setflags;
5192        switch (encoding)
5193        {
5194        case eEncodingT1:
5195            Rd = Rn = Bits32(opcode, 2, 0);
5196            Rm = Bits32(opcode, 5, 3);
5197            setflags = !InITBlock();
5198            shift_t = SRType_LSL;
5199            shift_n = 0;
5200            break;
5201        case eEncodingT2:
5202            Rd = Bits32(opcode, 11, 8);
5203            Rn = Bits32(opcode, 19, 16);
5204            Rm = Bits32(opcode, 3, 0);
5205            setflags = BitIsSet(opcode, 20);
5206            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5207            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5208                return false;
5209            break;
5210        case eEncodingA1:
5211            Rd = Bits32(opcode, 15, 12);
5212            Rn = Bits32(opcode, 19, 16);
5213            Rm = Bits32(opcode, 3, 0);
5214            setflags = BitIsSet(opcode, 20);
5215            shift_n = DecodeImmShiftARM(opcode, shift_t);
5216
5217            if (Rd == 15 && setflags)
5218                return EmulateSUBSPcLrEtc (opcode, encoding);
5219            break;
5220        default:
5221            return false;
5222        }
5223
5224        // Read the first operand.
5225        int32_t val1 = ReadCoreReg(Rn, &success);
5226        if (!success)
5227            return false;
5228
5229        // Read the second operand.
5230        int32_t val2 = ReadCoreReg(Rm, &success);
5231        if (!success)
5232            return false;
5233
5234        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
5235        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5236
5237        EmulateInstruction::Context context;
5238        context.type = EmulateInstruction::eContextImmediate;
5239        context.SetNoArgs ();
5240
5241        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5242            return false;
5243    }
5244    return true;
5245}
5246
5247// This instruction adds an immediate value to the PC value to form a PC-relative address,
5248// and writes the result to the destination register.
5249bool
5250EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5251{
5252#if 0
5253    // ARM pseudo code...
5254    if ConditionPassed() then
5255        EncodingSpecificOperations();
5256        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5257        if d == 15 then         // Can only occur for ARM encodings
5258            ALUWritePC(result);
5259        else
5260            R[d] = result;
5261#endif
5262
5263    bool success = false;
5264
5265    if (ConditionPassed(opcode))
5266    {
5267        uint32_t Rd;
5268        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5269        bool add;
5270        switch (encoding)
5271        {
5272        case eEncodingT1:
5273            Rd = Bits32(opcode, 10, 8);
5274            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5275            break;
5276        case eEncodingT2:
5277        case eEncodingT3:
5278            Rd = Bits32(opcode, 11, 8);
5279            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5280            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5281            if (BadReg(Rd))
5282                return false;
5283            break;
5284        case eEncodingA1:
5285        case eEncodingA2:
5286            Rd = Bits32(opcode, 15, 12);
5287            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5288            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5289            break;
5290        default:
5291            return false;
5292        }
5293
5294        // Read the PC value.
5295        uint32_t pc = ReadCoreReg(PC_REG, &success);
5296        if (!success)
5297            return false;
5298
5299        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5300
5301        EmulateInstruction::Context context;
5302        context.type = EmulateInstruction::eContextImmediate;
5303        context.SetNoArgs ();
5304
5305        if (!WriteCoreReg(context, result, Rd))
5306            return false;
5307    }
5308    return true;
5309}
5310
5311// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5312// to the destination register.  It can optionally update the condition flags based on the result.
5313bool
5314EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5315{
5316#if 0
5317    // ARM pseudo code...
5318    if ConditionPassed() then
5319        EncodingSpecificOperations();
5320        result = R[n] AND imm32;
5321        if d == 15 then         // Can only occur for ARM encoding
5322            ALUWritePC(result); // setflags is always FALSE here
5323        else
5324            R[d] = result;
5325            if setflags then
5326                APSR.N = result<31>;
5327                APSR.Z = IsZeroBit(result);
5328                APSR.C = carry;
5329                // APSR.V unchanged
5330#endif
5331
5332    bool success = false;
5333
5334    if (ConditionPassed(opcode))
5335    {
5336        uint32_t Rd, Rn;
5337        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5338        bool setflags;
5339        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5340        switch (encoding)
5341        {
5342        case eEncodingT1:
5343            Rd = Bits32(opcode, 11, 8);
5344            Rn = Bits32(opcode, 19, 16);
5345            setflags = BitIsSet(opcode, 20);
5346            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5347            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5348            if (Rd == 15 && setflags)
5349                return EmulateTSTImm(opcode, eEncodingT1);
5350            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5351                return false;
5352            break;
5353        case eEncodingA1:
5354            Rd = Bits32(opcode, 15, 12);
5355            Rn = Bits32(opcode, 19, 16);
5356            setflags = BitIsSet(opcode, 20);
5357            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5358
5359            if (Rd == 15 && setflags)
5360                return EmulateSUBSPcLrEtc (opcode, encoding);
5361            break;
5362        default:
5363            return false;
5364        }
5365
5366        // Read the first operand.
5367        uint32_t val1 = ReadCoreReg(Rn, &success);
5368        if (!success)
5369            return false;
5370
5371        uint32_t result = val1 & imm32;
5372
5373        EmulateInstruction::Context context;
5374        context.type = EmulateInstruction::eContextImmediate;
5375        context.SetNoArgs ();
5376
5377        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5378            return false;
5379    }
5380    return true;
5381}
5382
5383// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5384// and writes the result to the destination register.  It can optionally update the condition flags
5385// based on the result.
5386bool
5387EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5388{
5389#if 0
5390    // ARM pseudo code...
5391    if ConditionPassed() then
5392        EncodingSpecificOperations();
5393        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5394        result = R[n] AND shifted;
5395        if d == 15 then         // Can only occur for ARM encoding
5396            ALUWritePC(result); // setflags is always FALSE here
5397        else
5398            R[d] = result;
5399            if setflags then
5400                APSR.N = result<31>;
5401                APSR.Z = IsZeroBit(result);
5402                APSR.C = carry;
5403                // APSR.V unchanged
5404#endif
5405
5406    bool success = false;
5407
5408    if (ConditionPassed(opcode))
5409    {
5410        uint32_t Rd, Rn, Rm;
5411        ARM_ShifterType shift_t;
5412        uint32_t shift_n; // the shift applied to the value read from Rm
5413        bool setflags;
5414        uint32_t carry;
5415        switch (encoding)
5416        {
5417        case eEncodingT1:
5418            Rd = Rn = Bits32(opcode, 2, 0);
5419            Rm = Bits32(opcode, 5, 3);
5420            setflags = !InITBlock();
5421            shift_t = SRType_LSL;
5422            shift_n = 0;
5423            break;
5424        case eEncodingT2:
5425            Rd = Bits32(opcode, 11, 8);
5426            Rn = Bits32(opcode, 19, 16);
5427            Rm = Bits32(opcode, 3, 0);
5428            setflags = BitIsSet(opcode, 20);
5429            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5430            // if Rd == '1111' && S == '1' then SEE TST (register);
5431            if (Rd == 15 && setflags)
5432                return EmulateTSTReg(opcode, eEncodingT2);
5433            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5434                return false;
5435            break;
5436        case eEncodingA1:
5437            Rd = Bits32(opcode, 15, 12);
5438            Rn = Bits32(opcode, 19, 16);
5439            Rm = Bits32(opcode, 3, 0);
5440            setflags = BitIsSet(opcode, 20);
5441            shift_n = DecodeImmShiftARM(opcode, shift_t);
5442
5443            if (Rd == 15 && setflags)
5444                return EmulateSUBSPcLrEtc (opcode, encoding);
5445            break;
5446        default:
5447            return false;
5448        }
5449
5450        // Read the first operand.
5451        uint32_t val1 = ReadCoreReg(Rn, &success);
5452        if (!success)
5453            return false;
5454
5455        // Read the second operand.
5456        uint32_t val2 = ReadCoreReg(Rm, &success);
5457        if (!success)
5458            return false;
5459
5460        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5461        uint32_t result = val1 & shifted;
5462
5463        EmulateInstruction::Context context;
5464        context.type = EmulateInstruction::eContextImmediate;
5465        context.SetNoArgs ();
5466
5467        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5468            return false;
5469    }
5470    return true;
5471}
5472
5473// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5474// immediate value, and writes the result to the destination register.  It can optionally update the
5475// condition flags based on the result.
5476bool
5477EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5478{
5479#if 0
5480    // ARM pseudo code...
5481    if ConditionPassed() then
5482        EncodingSpecificOperations();
5483        result = R[n] AND NOT(imm32);
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;
5500        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5501        bool setflags;
5502        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5503        switch (encoding)
5504        {
5505        case eEncodingT1:
5506            Rd = Bits32(opcode, 11, 8);
5507            Rn = Bits32(opcode, 19, 16);
5508            setflags = BitIsSet(opcode, 20);
5509            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5510            if (BadReg(Rd) || BadReg(Rn))
5511                return false;
5512            break;
5513        case eEncodingA1:
5514            Rd = Bits32(opcode, 15, 12);
5515            Rn = Bits32(opcode, 19, 16);
5516            setflags = BitIsSet(opcode, 20);
5517            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5518
5519            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5520            if (Rd == 15 && setflags)
5521                return EmulateSUBSPcLrEtc (opcode, encoding);
5522            break;
5523        default:
5524            return false;
5525        }
5526
5527        // Read the first operand.
5528        uint32_t val1 = ReadCoreReg(Rn, &success);
5529        if (!success)
5530            return false;
5531
5532        uint32_t result = val1 & ~imm32;
5533
5534        EmulateInstruction::Context context;
5535        context.type = EmulateInstruction::eContextImmediate;
5536        context.SetNoArgs ();
5537
5538        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5539            return false;
5540    }
5541    return true;
5542}
5543
5544// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5545// optionally-shifted register value, and writes the result to the destination register.
5546// It can optionally update the condition flags based on the result.
5547bool
5548EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5549{
5550#if 0
5551    // ARM pseudo code...
5552    if ConditionPassed() then
5553        EncodingSpecificOperations();
5554        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5555        result = R[n] AND NOT(shifted);
5556        if d == 15 then         // Can only occur for ARM encoding
5557            ALUWritePC(result); // setflags is always FALSE here
5558        else
5559            R[d] = result;
5560            if setflags then
5561                APSR.N = result<31>;
5562                APSR.Z = IsZeroBit(result);
5563                APSR.C = carry;
5564                // APSR.V unchanged
5565#endif
5566
5567    bool success = false;
5568
5569    if (ConditionPassed(opcode))
5570    {
5571        uint32_t Rd, Rn, Rm;
5572        ARM_ShifterType shift_t;
5573        uint32_t shift_n; // the shift applied to the value read from Rm
5574        bool setflags;
5575        uint32_t carry;
5576        switch (encoding)
5577        {
5578        case eEncodingT1:
5579            Rd = Rn = Bits32(opcode, 2, 0);
5580            Rm = Bits32(opcode, 5, 3);
5581            setflags = !InITBlock();
5582            shift_t = SRType_LSL;
5583            shift_n = 0;
5584            break;
5585        case eEncodingT2:
5586            Rd = Bits32(opcode, 11, 8);
5587            Rn = Bits32(opcode, 19, 16);
5588            Rm = Bits32(opcode, 3, 0);
5589            setflags = BitIsSet(opcode, 20);
5590            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5591            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5592                return false;
5593            break;
5594        case eEncodingA1:
5595            Rd = Bits32(opcode, 15, 12);
5596            Rn = Bits32(opcode, 19, 16);
5597            Rm = Bits32(opcode, 3, 0);
5598            setflags = BitIsSet(opcode, 20);
5599            shift_n = DecodeImmShiftARM(opcode, shift_t);
5600
5601            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5602            if (Rd == 15 && setflags)
5603                return EmulateSUBSPcLrEtc (opcode, encoding);
5604            break;
5605        default:
5606            return false;
5607        }
5608
5609        // Read the first operand.
5610        uint32_t val1 = ReadCoreReg(Rn, &success);
5611        if (!success)
5612            return false;
5613
5614        // Read the second operand.
5615        uint32_t val2 = ReadCoreReg(Rm, &success);
5616        if (!success)
5617            return false;
5618
5619        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5620        uint32_t result = val1 & ~shifted;
5621
5622        EmulateInstruction::Context context;
5623        context.type = EmulateInstruction::eContextImmediate;
5624        context.SetNoArgs ();
5625
5626        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5627            return false;
5628    }
5629    return true;
5630}
5631
5632// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5633// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5634bool
5635EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5636{
5637#if 0
5638    if ConditionPassed() then
5639        EncodingSpecificOperations();
5640        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5641        address = if index then offset_addr else R[n];
5642        data = MemU[address,4];
5643        if wback then R[n] = offset_addr;
5644        if t == 15 then
5645            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5646        elsif UnalignedSupport() || address<1:0> = '00' then
5647            R[t] = data;
5648        else // Can only apply before ARMv7
5649            R[t] = ROR(data, 8*UInt(address<1:0>));
5650#endif
5651
5652    bool success = false;
5653
5654    if (ConditionPassed(opcode))
5655    {
5656        const uint32_t addr_byte_size = GetAddressByteSize();
5657
5658        uint32_t t;
5659        uint32_t n;
5660        uint32_t imm32;
5661        bool index;
5662        bool add;
5663        bool wback;
5664
5665        switch (encoding)
5666        {
5667            case eEncodingA1:
5668                // if Rn == '1111' then SEE LDR (literal);
5669                // if P == '0' && W == '1' then SEE LDRT;
5670                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5671                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5672                t = Bits32 (opcode, 15, 12);
5673                n = Bits32 (opcode, 19, 16);
5674                imm32 = Bits32 (opcode, 11, 0);
5675
5676                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5677                index = BitIsSet (opcode, 24);
5678                add = BitIsSet (opcode, 23);
5679                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5680
5681                // if wback && n == t then UNPREDICTABLE;
5682                if (wback && (n == t))
5683                    return false;
5684
5685                break;
5686
5687            default:
5688                return false;
5689        }
5690
5691        addr_t address;
5692        addr_t offset_addr;
5693        addr_t base_address = ReadCoreReg (n, &success);
5694        if (!success)
5695            return false;
5696
5697        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5698        if (add)
5699            offset_addr = base_address + imm32;
5700        else
5701            offset_addr = base_address - imm32;
5702
5703        // address = if index then offset_addr else R[n];
5704        if (index)
5705            address = offset_addr;
5706        else
5707            address = base_address;
5708
5709        // data = MemU[address,4];
5710
5711        Register base_reg;
5712        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5713
5714        EmulateInstruction::Context context;
5715        context.type = eContextRegisterLoad;
5716        context.SetRegisterPlusOffset (base_reg, address - base_address);
5717
5718        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5719        if (!success)
5720            return false;
5721
5722        // if wback then R[n] = offset_addr;
5723        if (wback)
5724        {
5725            context.type = eContextAdjustBaseRegister;
5726            context.SetAddress (offset_addr);
5727            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5728                return false;
5729        }
5730
5731        // if t == 15 then
5732        if (t == 15)
5733        {
5734            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5735            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5736            {
5737                // LoadWritePC (data);
5738                context.type = eContextRegisterLoad;
5739                context.SetRegisterPlusOffset (base_reg, address - base_address);
5740                LoadWritePC (context, data);
5741            }
5742            else
5743                  return false;
5744        }
5745        // elsif UnalignedSupport() || address<1:0> = '00' then
5746        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5747        {
5748            // R[t] = data;
5749            context.type = eContextRegisterLoad;
5750            context.SetRegisterPlusOffset (base_reg, address - base_address);
5751            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5752                return false;
5753        }
5754        // else // Can only apply before ARMv7
5755        else
5756        {
5757            // R[t] = ROR(data, 8*UInt(address<1:0>));
5758            data = ROR (data, Bits32 (address, 1, 0));
5759            context.type = eContextRegisterLoad;
5760            context.SetImmediate (data);
5761            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5762                return false;
5763        }
5764
5765    }
5766    return true;
5767}
5768
5769// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5770// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5771bool
5772EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5773{
5774#if 0
5775    if ConditionPassed() then
5776        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5777        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5778        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5779        address = if index then offset_addr else R[n];
5780        data = MemU[address,4];
5781        if wback then R[n] = offset_addr;
5782        if t == 15 then
5783            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5784        elsif UnalignedSupport() || address<1:0> = '00' then
5785            R[t] = data;
5786        else // Can only apply before ARMv7
5787            if CurrentInstrSet() == InstrSet_ARM then
5788                R[t] = ROR(data, 8*UInt(address<1:0>));
5789            else
5790                R[t] = bits(32) UNKNOWN;
5791#endif
5792
5793    bool success = false;
5794
5795    if (ConditionPassed(opcode))
5796    {
5797        const uint32_t addr_byte_size = GetAddressByteSize();
5798
5799        uint32_t t;
5800        uint32_t n;
5801        uint32_t m;
5802        bool index;
5803        bool add;
5804        bool wback;
5805        ARM_ShifterType shift_t;
5806        uint32_t shift_n;
5807
5808        switch (encoding)
5809        {
5810            case eEncodingT1:
5811                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5812                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5813                t = Bits32 (opcode, 2, 0);
5814                n = Bits32 (opcode, 5, 3);
5815                m = Bits32 (opcode, 8, 6);
5816
5817                // index = TRUE; add = TRUE; wback = FALSE;
5818                index = true;
5819                add = true;
5820                wback = false;
5821
5822                // (shift_t, shift_n) = (SRType_LSL, 0);
5823                shift_t = SRType_LSL;
5824                shift_n = 0;
5825
5826                break;
5827
5828            case eEncodingT2:
5829                // if Rn == '1111' then SEE LDR (literal);
5830                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5831                t = Bits32 (opcode, 15, 12);
5832                n = Bits32 (opcode, 19, 16);
5833                m = Bits32 (opcode, 3, 0);
5834
5835                // index = TRUE; add = TRUE; wback = FALSE;
5836                index = true;
5837                add = true;
5838                wback = false;
5839
5840                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5841                shift_t = SRType_LSL;
5842                shift_n = Bits32 (opcode, 5, 4);
5843
5844                // if BadReg(m) then UNPREDICTABLE;
5845                if (BadReg (m))
5846                    return false;
5847
5848                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5849                if ((t == 15) && InITBlock() && !LastInITBlock())
5850                    return false;
5851
5852                break;
5853
5854            case eEncodingA1:
5855            {
5856                // if P == '0' && W == '1' then SEE LDRT;
5857                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5858                t = Bits32 (opcode, 15, 12);
5859                n = Bits32 (opcode, 19, 16);
5860                m = Bits32 (opcode, 3, 0);
5861
5862                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5863                index = BitIsSet (opcode, 24);
5864                add = BitIsSet (opcode, 23);
5865                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5866
5867                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5868                uint32_t type = Bits32 (opcode, 6, 5);
5869                uint32_t imm5 = Bits32 (opcode, 11, 7);
5870                shift_n = DecodeImmShift (type, imm5, shift_t);
5871
5872                // if m == 15 then UNPREDICTABLE;
5873                if (m == 15)
5874                    return false;
5875
5876                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5877                if (wback && ((n == 15) || (n == t)))
5878                    return false;
5879            }
5880                break;
5881
5882
5883            default:
5884                return false;
5885        }
5886
5887        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5888        if (!success)
5889            return false;
5890
5891        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5892        if (!success)
5893            return false;
5894
5895        addr_t offset_addr;
5896        addr_t address;
5897
5898        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
5899        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C));
5900
5901        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5902        if (add)
5903            offset_addr = Rn + offset;
5904        else
5905            offset_addr = Rn - offset;
5906
5907        // address = if index then offset_addr else R[n];
5908            if (index)
5909                address = offset_addr;
5910            else
5911                address = Rn;
5912
5913        // data = MemU[address,4];
5914        Register base_reg;
5915        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5916
5917        EmulateInstruction::Context context;
5918        context.type = eContextRegisterLoad;
5919        context.SetRegisterPlusOffset (base_reg, address - Rn);
5920
5921        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5922        if (!success)
5923            return false;
5924
5925        // if wback then R[n] = offset_addr;
5926        if (wback)
5927        {
5928            context.type = eContextAdjustBaseRegister;
5929            context.SetAddress (offset_addr);
5930            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5931                return false;
5932        }
5933
5934        // if t == 15 then
5935        if (t == 15)
5936        {
5937            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5938            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5939            {
5940                context.type = eContextRegisterLoad;
5941                context.SetRegisterPlusOffset (base_reg, address - Rn);
5942                LoadWritePC (context, data);
5943            }
5944            else
5945                return false;
5946        }
5947        // elsif UnalignedSupport() || address<1:0> = '00' then
5948        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5949        {
5950            // R[t] = data;
5951            context.type = eContextRegisterLoad;
5952            context.SetRegisterPlusOffset (base_reg, address - Rn);
5953            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5954                return false;
5955        }
5956        else // Can only apply before ARMv7
5957        {
5958            // if CurrentInstrSet() == InstrSet_ARM then
5959            if (CurrentInstrSet () == eModeARM)
5960            {
5961                // R[t] = ROR(data, 8*UInt(address<1:0>));
5962                data = ROR (data, Bits32 (address, 1, 0));
5963                context.type = eContextRegisterLoad;
5964                context.SetImmediate (data);
5965                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5966                    return false;
5967            }
5968            else
5969            {
5970                // R[t] = bits(32) UNKNOWN;
5971                WriteBits32Unknown (t);
5972            }
5973        }
5974    }
5975    return true;
5976}
5977
5978// LDRB (immediate, Thumb)
5979bool
5980EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
5981{
5982#if 0
5983    if ConditionPassed() then
5984        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5985        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5986        address = if index then offset_addr else R[n];
5987        R[t] = ZeroExtend(MemU[address,1], 32);
5988        if wback then R[n] = offset_addr;
5989#endif
5990
5991    bool success = false;
5992
5993    if (ConditionPassed(opcode))
5994    {
5995        uint32_t t;
5996        uint32_t n;
5997        uint32_t imm32;
5998        bool index;
5999        bool add;
6000        bool wback;
6001
6002        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6003        switch (encoding)
6004        {
6005            case eEncodingT1:
6006                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6007                t = Bits32 (opcode, 2, 0);
6008                n = Bits32 (opcode, 5, 3);
6009                imm32 = Bits32 (opcode, 10, 6);
6010
6011                // index = TRUE; add = TRUE; wback = FALSE;
6012                index = true;
6013                add = true;
6014                wback= false;
6015
6016                break;
6017
6018            case eEncodingT2:
6019                // if Rt == '1111' then SEE PLD;
6020                // if Rn == '1111' then SEE LDRB (literal);
6021                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6022                t = Bits32 (opcode, 15, 12);
6023                n = Bits32 (opcode, 19, 16);
6024                imm32 = Bits32 (opcode, 11, 0);
6025
6026                // index = TRUE; add = TRUE; wback = FALSE;
6027                index = true;
6028                add = true;
6029                wback = false;
6030
6031                // if t == 13 then UNPREDICTABLE;
6032                if (t == 13)
6033                    return false;
6034
6035                break;
6036
6037            case eEncodingT3:
6038                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6039                // if Rn == '1111' then SEE LDRB (literal);
6040                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6041                // if P == '0' && W == '0' then UNDEFINED;
6042                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6043                    return false;
6044
6045                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6046                t = Bits32 (opcode, 15, 12);
6047                n = Bits32 (opcode, 19, 16);
6048                imm32 = Bits32 (opcode, 7, 0);
6049
6050                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6051                index = BitIsSet (opcode, 10);
6052                add = BitIsSet (opcode, 9);
6053                wback = BitIsSet (opcode, 8);
6054
6055                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6056                if (BadReg (t) || (wback && (n == t)))
6057                    return false;
6058
6059                break;
6060
6061            default:
6062                return false;
6063        }
6064
6065        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6066        if (!success)
6067            return false;
6068
6069        addr_t address;
6070        addr_t offset_addr;
6071
6072        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6073        if (add)
6074            offset_addr = Rn + imm32;
6075        else
6076            offset_addr = Rn - imm32;
6077
6078        // address = if index then offset_addr else R[n];
6079        if (index)
6080            address = offset_addr;
6081        else
6082            address = Rn;
6083
6084        // R[t] = ZeroExtend(MemU[address,1], 32);
6085        Register base_reg;
6086        Register data_reg;
6087        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6088        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
6089
6090        EmulateInstruction::Context context;
6091        context.type = eContextRegisterLoad;
6092        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6093
6094        uint64_t data = MemURead (context, address, 1, 0, &success);
6095        if (!success)
6096            return false;
6097
6098        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6099            return false;
6100
6101        // if wback then R[n] = offset_addr;
6102        if (wback)
6103        {
6104            context.type = eContextAdjustBaseRegister;
6105            context.SetAddress (offset_addr);
6106            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6107                return false;
6108        }
6109    }
6110    return true;
6111}
6112
6113// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6114// zero-extends it to form a 32-bit word and writes it to a register.
6115bool
6116EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6117{
6118#if 0
6119    if ConditionPassed() then
6120        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6121        base = Align(PC,4);
6122        address = if add then (base + imm32) else (base - imm32);
6123        R[t] = ZeroExtend(MemU[address,1], 32);
6124#endif
6125
6126    bool success = false;
6127
6128    if (ConditionPassed(opcode))
6129    {
6130        uint32_t t;
6131        uint32_t imm32;
6132        bool add;
6133        switch (encoding)
6134        {
6135            case eEncodingT1:
6136                // if Rt == '1111' then SEE PLD;
6137                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6138                t = Bits32 (opcode, 15, 12);
6139                imm32 = Bits32 (opcode, 11, 0);
6140                add = BitIsSet (opcode, 23);
6141
6142                // if t == 13 then UNPREDICTABLE;
6143                if (t == 13)
6144                    return false;
6145
6146                break;
6147
6148            case eEncodingA1:
6149                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6150                t = Bits32 (opcode, 15, 12);
6151                imm32 = Bits32 (opcode, 11, 0);
6152                add = BitIsSet (opcode, 23);
6153
6154                // if t == 15 then UNPREDICTABLE;
6155                if (t == 15)
6156                    return false;
6157                break;
6158
6159            default:
6160                return false;
6161        }
6162
6163        // base = Align(PC,4);
6164        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6165        if (!success)
6166            return false;
6167
6168        uint32_t base = AlignPC (pc_val);
6169
6170        addr_t address;
6171        // address = if add then (base + imm32) else (base - imm32);
6172        if (add)
6173            address = base + imm32;
6174        else
6175            address = base - imm32;
6176
6177        // R[t] = ZeroExtend(MemU[address,1], 32);
6178        EmulateInstruction::Context context;
6179        context.type = eContextRelativeBranchImmediate;
6180        context.SetImmediate (address - base);
6181
6182        uint64_t data = MemURead (context, address, 1, 0, &success);
6183        if (!success)
6184            return false;
6185
6186        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6187            return false;
6188    }
6189    return true;
6190}
6191
6192// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6193// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6194// optionally be shifted.
6195bool
6196EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6197{
6198#if 0
6199    if ConditionPassed() then
6200        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6201        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6202        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6203        address = if index then offset_addr else R[n];
6204        R[t] = ZeroExtend(MemU[address,1],32);
6205        if wback then R[n] = offset_addr;
6206#endif
6207
6208    bool success = false;
6209
6210    if (ConditionPassed(opcode))
6211    {
6212        uint32_t t;
6213        uint32_t n;
6214        uint32_t m;
6215        bool index;
6216        bool add;
6217        bool wback;
6218        ARM_ShifterType shift_t;
6219        uint32_t shift_n;
6220
6221        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6222        switch (encoding)
6223        {
6224            case eEncodingT1:
6225                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6226                t = Bits32 (opcode, 2, 0);
6227                n = Bits32 (opcode, 5, 3);
6228                m = Bits32 (opcode, 8, 6);
6229
6230                // index = TRUE; add = TRUE; wback = FALSE;
6231                index = true;
6232                add = true;
6233                wback = false;
6234
6235                // (shift_t, shift_n) = (SRType_LSL, 0);
6236                shift_t = SRType_LSL;
6237                shift_n = 0;
6238                break;
6239
6240            case eEncodingT2:
6241                // if Rt == '1111' then SEE PLD;
6242                // if Rn == '1111' then SEE LDRB (literal);
6243                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6244                t = Bits32 (opcode, 15, 12);
6245                n = Bits32 (opcode, 19, 16);
6246                m = Bits32 (opcode, 3, 0);
6247
6248                // index = TRUE; add = TRUE; wback = FALSE;
6249                index = true;
6250                add = true;
6251                wback = false;
6252
6253                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6254                shift_t = SRType_LSL;
6255                shift_n = Bits32 (opcode, 5, 4);
6256
6257                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6258                if ((t == 13) || BadReg (m))
6259                    return false;
6260                break;
6261
6262            case eEncodingA1:
6263            {
6264                // if P == '0' && W == '1' then SEE LDRBT;
6265                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6266                t = Bits32 (opcode, 15, 12);
6267                n = Bits32 (opcode, 19, 16);
6268                m = Bits32 (opcode, 3, 0);
6269
6270                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6271                index = BitIsSet (opcode, 24);
6272                add = BitIsSet (opcode, 23);
6273                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6274
6275                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6276                uint32_t type = Bits32 (opcode, 6, 5);
6277                uint32_t imm5 = Bits32 (opcode, 11, 7);
6278                shift_n = DecodeImmShift (type, imm5, shift_t);
6279
6280                // if t == 15 || m == 15 then UNPREDICTABLE;
6281                if ((t == 15) || (m == 15))
6282                    return false;
6283
6284                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6285                if (wback && ((n == 15) || (n == t)))
6286                    return false;
6287            }
6288                break;
6289
6290            default:
6291                return false;
6292        }
6293
6294        addr_t offset_addr;
6295        addr_t address;
6296
6297        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6298        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6299        if (!success)
6300            return false;
6301
6302        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6303
6304        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6305        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6306        if (!success)
6307            return false;
6308
6309        if (add)
6310            offset_addr = Rn + offset;
6311        else
6312            offset_addr = Rn - offset;
6313
6314        // address = if index then offset_addr else R[n];
6315        if (index)
6316            address = offset_addr;
6317        else
6318            address = Rn;
6319
6320        // R[t] = ZeroExtend(MemU[address,1],32);
6321        Register base_reg;
6322        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6323
6324        EmulateInstruction::Context context;
6325        context.type = eContextRegisterLoad;
6326        context.SetRegisterPlusOffset (base_reg, address - Rn);
6327
6328        uint64_t data = MemURead (context, address, 1, 0, &success);
6329        if (!success)
6330            return false;
6331
6332        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6333            return false;
6334
6335        // if wback then R[n] = offset_addr;
6336        if (wback)
6337        {
6338            context.type = eContextAdjustBaseRegister;
6339            context.SetAddress (offset_addr);
6340            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6341                return false;
6342        }
6343    }
6344    return true;
6345}
6346
6347// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6348// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6349// post-indexed, or pre-indexed addressing.
6350bool
6351EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6352{
6353#if 0
6354    if ConditionPassed() then
6355        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6356        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6357        address = if index then offset_addr else R[n];
6358        data = MemU[address,2];
6359        if wback then R[n] = offset_addr;
6360        if UnalignedSupport() || address<0> = '0' then
6361            R[t] = ZeroExtend(data, 32);
6362        else // Can only apply before ARMv7
6363            R[t] = bits(32) UNKNOWN;
6364#endif
6365
6366
6367    bool success = false;
6368
6369    if (ConditionPassed(opcode))
6370    {
6371        uint32_t t;
6372        uint32_t n;
6373        uint32_t imm32;
6374        bool index;
6375        bool add;
6376        bool wback;
6377
6378        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6379        switch (encoding)
6380        {
6381            case eEncodingT1:
6382                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6383                t = Bits32 (opcode, 2, 0);
6384                n = Bits32 (opcode, 5, 3);
6385                imm32 = Bits32 (opcode, 10, 6) << 1;
6386
6387                // index = TRUE; add = TRUE; wback = FALSE;
6388                index = true;
6389                add = true;
6390                wback = false;
6391
6392                break;
6393
6394            case eEncodingT2:
6395                // if Rt == '1111' then SEE "Unallocated memory hints";
6396                // if Rn == '1111' then SEE LDRH (literal);
6397                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6398                t = Bits32 (opcode, 15, 12);
6399                n = Bits32 (opcode, 19, 16);
6400                imm32 = Bits32 (opcode, 11, 0);
6401
6402                // index = TRUE; add = TRUE; wback = FALSE;
6403                index = true;
6404                add = true;
6405                wback = false;
6406
6407                // if t == 13 then UNPREDICTABLE;
6408                if (t == 13)
6409                    return false;
6410                break;
6411
6412            case eEncodingT3:
6413                // if Rn == '1111' then SEE LDRH (literal);
6414                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6415                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6416                // if P == '0' && W == '0' then UNDEFINED;
6417                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6418                    return false;
6419
6420                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6421                t = Bits32 (opcode, 15, 12);
6422                n = Bits32 (opcode, 19, 16);
6423                imm32 = Bits32 (opcode, 7, 0);
6424
6425                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6426                index = BitIsSet (opcode, 10);
6427                add = BitIsSet (opcode, 9);
6428                wback = BitIsSet (opcode, 8);
6429
6430                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6431                if (BadReg (t) || (wback && (n == t)))
6432                    return false;
6433                break;
6434
6435            default:
6436                return false;
6437        }
6438
6439        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6440        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6441        if (!success)
6442            return false;
6443
6444        addr_t offset_addr;
6445        addr_t address;
6446
6447        if (add)
6448            offset_addr = Rn + imm32;
6449        else
6450            offset_addr = Rn - imm32;
6451
6452        // address = if index then offset_addr else R[n];
6453        if (index)
6454            address = offset_addr;
6455        else
6456            address = Rn;
6457
6458        // data = MemU[address,2];
6459        Register base_reg;
6460        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6461
6462        EmulateInstruction::Context context;
6463        context.type = eContextRegisterLoad;
6464        context.SetRegisterPlusOffset (base_reg, address - Rn);
6465
6466        uint64_t data = MemURead (context, address, 2, 0, &success);
6467        if (!success)
6468            return false;
6469
6470        // if wback then R[n] = offset_addr;
6471        if (wback)
6472        {
6473            context.type = eContextAdjustBaseRegister;
6474            context.SetAddress (offset_addr);
6475            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6476                return false;
6477        }
6478
6479        // if UnalignedSupport() || address<0> = '0' then
6480        if (UnalignedSupport () || BitIsClear (address, 0))
6481        {
6482            // R[t] = ZeroExtend(data, 32);
6483            context.type = eContextRegisterLoad;
6484            context.SetRegisterPlusOffset (base_reg, address - Rn);
6485            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6486                return false;
6487        }
6488        else // Can only apply before ARMv7
6489        {
6490            // R[t] = bits(32) UNKNOWN;
6491            WriteBits32Unknown (t);
6492        }
6493    }
6494    return true;
6495}
6496
6497// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6498// zero-extends it to form a 32-bit word, and writes it to a register.
6499bool
6500EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6501{
6502#if 0
6503    if ConditionPassed() then
6504        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6505        base = Align(PC,4);
6506        address = if add then (base + imm32) else (base - imm32);
6507        data = MemU[address,2];
6508        if UnalignedSupport() || address<0> = '0' then
6509            R[t] = ZeroExtend(data, 32);
6510        else // Can only apply before ARMv7
6511            R[t] = bits(32) UNKNOWN;
6512#endif
6513
6514    bool success = false;
6515
6516    if (ConditionPassed(opcode))
6517    {
6518        uint32_t t;
6519        uint32_t imm32;
6520        bool add;
6521
6522        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6523        switch (encoding)
6524        {
6525            case eEncodingT1:
6526                // if Rt == '1111' then SEE "Unallocated memory hints";
6527                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6528                t = Bits32 (opcode, 15, 12);
6529                imm32 = Bits32 (opcode, 11, 0);
6530                add = BitIsSet (opcode, 23);
6531
6532                // if t == 13 then UNPREDICTABLE;
6533                if (t == 13)
6534                    return false;
6535
6536                break;
6537
6538            case eEncodingA1:
6539            {
6540                uint32_t imm4H = Bits32 (opcode, 11, 8);
6541                uint32_t imm4L = Bits32 (opcode, 3, 0);
6542
6543                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6544                t = Bits32 (opcode, 15, 12);
6545                imm32 = (imm4H << 4) | imm4L;
6546                add = BitIsSet (opcode, 23);
6547
6548                // if t == 15 then UNPREDICTABLE;
6549                if (t == 15)
6550                    return false;
6551                break;
6552            }
6553
6554            default:
6555                return false;
6556        }
6557
6558        // base = Align(PC,4);
6559        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6560        if (!success)
6561            return false;
6562
6563        addr_t base = AlignPC (pc_value);
6564        addr_t address;
6565
6566        // address = if add then (base + imm32) else (base - imm32);
6567        if (add)
6568            address = base + imm32;
6569        else
6570            address = base - imm32;
6571
6572        // data = MemU[address,2];
6573        Register base_reg;
6574        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
6575
6576        EmulateInstruction::Context context;
6577        context.type = eContextRegisterLoad;
6578        context.SetRegisterPlusOffset (base_reg, address - base);
6579
6580        uint64_t data = MemURead (context, address, 2, 0, &success);
6581        if (!success)
6582            return false;
6583
6584
6585        // if UnalignedSupport() || address<0> = '0' then
6586        if (UnalignedSupport () || BitIsClear (address, 0))
6587        {
6588            // R[t] = ZeroExtend(data, 32);
6589            context.type = eContextRegisterLoad;
6590            context.SetRegisterPlusOffset (base_reg, address - base);
6591            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6592                return false;
6593
6594        }
6595        else // Can only apply before ARMv7
6596        {
6597            // R[t] = bits(32) UNKNOWN;
6598            WriteBits32Unknown (t);
6599        }
6600    }
6601    return true;
6602}
6603
6604// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6605// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6606// be shifted left by 0, 1, 2, or 3 bits.
6607bool
6608EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6609{
6610#if 0
6611    if ConditionPassed() then
6612        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6613        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6614        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6615        address = if index then offset_addr else R[n];
6616        data = MemU[address,2];
6617        if wback then R[n] = offset_addr;
6618        if UnalignedSupport() || address<0> = '0' then
6619            R[t] = ZeroExtend(data, 32);
6620        else // Can only apply before ARMv7
6621            R[t] = bits(32) UNKNOWN;
6622#endif
6623
6624    bool success = false;
6625
6626    if (ConditionPassed(opcode))
6627    {
6628        uint32_t t;
6629        uint32_t n;
6630        uint32_t m;
6631        bool index;
6632        bool add;
6633        bool wback;
6634        ARM_ShifterType shift_t;
6635        uint32_t shift_n;
6636
6637        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6638        switch (encoding)
6639        {
6640            case eEncodingT1:
6641                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6642                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6643                t = Bits32 (opcode, 2, 0);
6644                n = Bits32 (opcode, 5, 3);
6645                m = Bits32 (opcode, 8, 6);
6646
6647                // index = TRUE; add = TRUE; wback = FALSE;
6648                index = true;
6649                add = true;
6650                wback = false;
6651
6652                // (shift_t, shift_n) = (SRType_LSL, 0);
6653                shift_t = SRType_LSL;
6654                shift_n = 0;
6655
6656                break;
6657
6658            case eEncodingT2:
6659                // if Rn == '1111' then SEE LDRH (literal);
6660                // if Rt == '1111' then SEE "Unallocated memory hints";
6661                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6662                t = Bits32 (opcode, 15, 12);
6663                n = Bits32 (opcode, 19, 16);
6664                m = Bits32 (opcode, 3, 0);
6665
6666                // index = TRUE; add = TRUE; wback = FALSE;
6667                index = true;
6668                add = true;
6669                wback = false;
6670
6671                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6672                shift_t = SRType_LSL;
6673                shift_n = Bits32 (opcode, 5, 4);
6674
6675                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6676                if ((t == 13) || BadReg (m))
6677                    return false;
6678                break;
6679
6680            case eEncodingA1:
6681                // if P == '0' && W == '1' then SEE LDRHT;
6682                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6683                t = Bits32 (opcode, 15, 12);
6684                n = Bits32 (opcode, 19, 16);
6685                m = Bits32 (opcode, 3, 0);
6686
6687                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6688                index = BitIsSet (opcode, 24);
6689                add = BitIsSet (opcode, 23);
6690                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6691
6692                // (shift_t, shift_n) = (SRType_LSL, 0);
6693                shift_t = SRType_LSL;
6694                shift_n = 0;
6695
6696                // if t == 15 || m == 15 then UNPREDICTABLE;
6697                if ((t == 15) || (m == 15))
6698                    return false;
6699
6700                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6701                if (wback && ((n == 15) || (n == t)))
6702                    return false;
6703
6704                break;
6705
6706            default:
6707                return false;
6708        }
6709
6710        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6711
6712        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6713        if (!success)
6714            return false;
6715
6716        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6717
6718        addr_t offset_addr;
6719        addr_t address;
6720
6721        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6722        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6723        if (!success)
6724            return false;
6725
6726        if (add)
6727            offset_addr = Rn + offset;
6728        else
6729            offset_addr = Rn - offset;
6730
6731        // address = if index then offset_addr else R[n];
6732        if (index)
6733            address = offset_addr;
6734        else
6735            address = Rn;
6736
6737        // data = MemU[address,2];
6738        Register base_reg;
6739        Register offset_reg;
6740        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6741        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
6742
6743        EmulateInstruction::Context context;
6744        context.type = eContextRegisterLoad;
6745        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6746        uint64_t data = MemURead (context, address, 2, 0, &success);
6747        if (!success)
6748            return false;
6749
6750        // if wback then R[n] = offset_addr;
6751        if (wback)
6752        {
6753            context.type = eContextAdjustBaseRegister;
6754            context.SetAddress (offset_addr);
6755            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6756                return false;
6757        }
6758
6759        // if UnalignedSupport() || address<0> = '0' then
6760        if (UnalignedSupport() || BitIsClear (address, 0))
6761        {
6762            // R[t] = ZeroExtend(data, 32);
6763            context.type = eContextRegisterLoad;
6764            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6765            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6766                return false;
6767        }
6768        else // Can only apply before ARMv7
6769        {
6770            // R[t] = bits(32) UNKNOWN;
6771            WriteBits32Unknown (t);
6772        }
6773    }
6774    return true;
6775}
6776
6777// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6778// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6779// or pre-indexed addressing.
6780bool
6781EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6782{
6783#if 0
6784    if ConditionPassed() then
6785        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6786        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6787        address = if index then offset_addr else R[n];
6788        R[t] = SignExtend(MemU[address,1], 32);
6789        if wback then R[n] = offset_addr;
6790#endif
6791
6792    bool success = false;
6793
6794    if (ConditionPassed(opcode))
6795    {
6796        uint32_t t;
6797        uint32_t n;
6798        uint32_t imm32;
6799        bool index;
6800        bool add;
6801        bool wback;
6802
6803        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6804        switch (encoding)
6805        {
6806            case eEncodingT1:
6807                // if Rt == '1111' then SEE PLI;
6808                // if Rn == '1111' then SEE LDRSB (literal);
6809                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6810                t = Bits32 (opcode, 15, 12);
6811                n = Bits32 (opcode, 19, 16);
6812                imm32 = Bits32 (opcode, 11, 0);
6813
6814                // index = TRUE; add = TRUE; wback = FALSE;
6815                index = true;
6816                add = true;
6817                wback = false;
6818
6819                // if t == 13 then UNPREDICTABLE;
6820                if (t == 13)
6821                    return false;
6822
6823                break;
6824
6825            case eEncodingT2:
6826                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6827                // if Rn == '1111' then SEE LDRSB (literal);
6828                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6829                // if P == '0' && W == '0' then UNDEFINED;
6830                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6831                    return false;
6832
6833                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6834                t = Bits32 (opcode, 15, 12);
6835                n = Bits32 (opcode, 19, 16);
6836                imm32 = Bits32 (opcode, 7, 0);
6837
6838                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6839                index = BitIsSet (opcode, 10);
6840                add = BitIsSet (opcode, 9);
6841                wback = BitIsSet (opcode, 8);
6842
6843                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6844                  if (((t == 13) || ((t == 15)
6845                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6846                      || (wback && (n == t)))
6847                    return false;
6848
6849                break;
6850
6851            case eEncodingA1:
6852            {
6853                // if Rn == '1111' then SEE LDRSB (literal);
6854                // if P == '0' && W == '1' then SEE LDRSBT;
6855                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6856                t = Bits32 (opcode, 15, 12);
6857                n = Bits32 (opcode, 19, 16);
6858
6859                uint32_t imm4H = Bits32 (opcode, 11, 8);
6860                uint32_t imm4L = Bits32 (opcode, 3, 0);
6861                imm32 = (imm4H << 4) | imm4L;
6862
6863                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6864                index = BitIsSet (opcode, 24);
6865                add = BitIsSet (opcode, 23);
6866                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6867
6868                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
6869                if ((t == 15) || (wback && (n == t)))
6870                    return false;
6871
6872                break;
6873            }
6874
6875            default:
6876                return false;
6877        }
6878
6879        uint64_t Rn = ReadCoreReg (n, &success);
6880        if (!success)
6881            return false;
6882
6883        addr_t offset_addr;
6884        addr_t address;
6885
6886        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6887        if (add)
6888            offset_addr = Rn + imm32;
6889        else
6890            offset_addr = Rn - imm32;
6891
6892        // address = if index then offset_addr else R[n];
6893        if (index)
6894            address = offset_addr;
6895        else
6896            address = Rn;
6897
6898        // R[t] = SignExtend(MemU[address,1], 32);
6899        Register base_reg;
6900        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6901
6902        EmulateInstruction::Context context;
6903        context.type = eContextRegisterLoad;
6904        context.SetRegisterPlusOffset (base_reg, address - Rn);
6905
6906        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
6907        if (!success)
6908            return false;
6909
6910        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
6911        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
6912            return false;
6913
6914        // if wback then R[n] = offset_addr;
6915        if (wback)
6916        {
6917            context.type = eContextAdjustBaseRegister;
6918            context.SetAddress (offset_addr);
6919            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6920                return false;
6921        }
6922    }
6923
6924    return true;
6925}
6926
6927// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6928// sign-extends it to form a 32-bit word, and writes tit to a register.
6929bool
6930EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6931{
6932#if 0
6933    if ConditionPassed() then
6934        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6935        base = Align(PC,4);
6936        address = if add then (base + imm32) else (base - imm32);
6937        R[t] = SignExtend(MemU[address,1], 32);
6938#endif
6939
6940    bool success = false;
6941
6942    if (ConditionPassed(opcode))
6943    {
6944        uint32_t t;
6945        uint32_t imm32;
6946        bool add;
6947
6948        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6949        switch (encoding)
6950        {
6951            case eEncodingT1:
6952                // if Rt == '1111' then SEE PLI;
6953                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6954                t = Bits32 (opcode, 15, 12);
6955                imm32 = Bits32 (opcode, 11, 0);
6956                add = BitIsSet (opcode, 23);
6957
6958                // if t == 13 then UNPREDICTABLE;
6959                if (t == 13)
6960                    return false;
6961
6962                break;
6963
6964            case eEncodingA1:
6965            {
6966                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6967                t = Bits32 (opcode, 15, 12);
6968                uint32_t imm4H = Bits32 (opcode, 11, 8);
6969                uint32_t imm4L = Bits32 (opcode, 3, 0);
6970                imm32 = (imm4H << 4) | imm4L;
6971                add = BitIsSet (opcode, 23);
6972
6973                // if t == 15 then UNPREDICTABLE;
6974                if (t == 15)
6975                    return false;
6976
6977                break;
6978            }
6979
6980            default:
6981                return false;
6982        }
6983
6984        // base = Align(PC,4);
6985        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6986        if (!success)
6987            return false;
6988        uint64_t base = AlignPC (pc_value);
6989
6990        // address = if add then (base + imm32) else (base - imm32);
6991        addr_t address;
6992        if (add)
6993            address = base + imm32;
6994        else
6995            address = base - imm32;
6996
6997        // R[t] = SignExtend(MemU[address,1], 32);
6998        Register base_reg;
6999        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7000
7001        EmulateInstruction::Context context;
7002        context.type = eContextRegisterLoad;
7003        context.SetRegisterPlusOffset (base_reg, address - base);
7004
7005        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7006        if (!success)
7007            return false;
7008
7009        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7010        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7011            return false;
7012    }
7013    return true;
7014}
7015
7016// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7017// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7018// shifted left by 0, 1, 2, or 3 bits.
7019bool
7020EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7021{
7022#if 0
7023    if ConditionPassed() then
7024        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7025        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7026        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7027        address = if index then offset_addr else R[n];
7028        R[t] = SignExtend(MemU[address,1], 32);
7029        if wback then R[n] = offset_addr;
7030#endif
7031
7032    bool success = false;
7033
7034    if (ConditionPassed(opcode))
7035    {
7036        uint32_t t;
7037        uint32_t n;
7038        uint32_t m;
7039        bool index;
7040        bool add;
7041        bool wback;
7042        ARM_ShifterType shift_t;
7043        uint32_t shift_n;
7044
7045        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7046        switch (encoding)
7047        {
7048            case eEncodingT1:
7049                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7050                t = Bits32 (opcode, 2, 0);
7051                n = Bits32 (opcode, 5, 3);
7052                m = Bits32 (opcode, 8, 6);
7053
7054                // index = TRUE; add = TRUE; wback = FALSE;
7055                index = true;
7056                add = true;
7057                wback = false;
7058
7059                // (shift_t, shift_n) = (SRType_LSL, 0);
7060                shift_t = SRType_LSL;
7061                shift_n = 0;
7062
7063                break;
7064
7065            case eEncodingT2:
7066                // if Rt == '1111' then SEE PLI;
7067                // if Rn == '1111' then SEE LDRSB (literal);
7068                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7069                t = Bits32 (opcode, 15, 12);
7070                n = Bits32 (opcode, 19, 16);
7071                m = Bits32 (opcode, 3, 0);
7072
7073                // index = TRUE; add = TRUE; wback = FALSE;
7074                index = true;
7075                add = true;
7076                wback = false;
7077
7078                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7079                shift_t = SRType_LSL;
7080                shift_n = Bits32 (opcode, 5, 4);
7081
7082                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7083                if ((t == 13) || BadReg (m))
7084                    return false;
7085                break;
7086
7087            case eEncodingA1:
7088                // if P == '0' && W == '1' then SEE LDRSBT;
7089                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7090                t = Bits32 (opcode, 15, 12);
7091                n = Bits32 (opcode, 19, 16);
7092                m = Bits32 (opcode, 3, 0);
7093
7094                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7095                index = BitIsSet (opcode, 24);
7096                add = BitIsSet (opcode, 23);
7097                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7098
7099                // (shift_t, shift_n) = (SRType_LSL, 0);
7100                shift_t = SRType_LSL;
7101                shift_n = 0;
7102
7103                // if t == 15 || m == 15 then UNPREDICTABLE;
7104                if ((t == 15) || (m == 15))
7105                    return false;
7106
7107                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7108                if (wback && ((n == 15) || (n == t)))
7109                    return false;
7110                break;
7111
7112            default:
7113                return false;
7114        }
7115
7116        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7117        if (!success)
7118            return false;
7119
7120        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7121        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7122
7123        addr_t offset_addr;
7124        addr_t address;
7125
7126        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7127        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7128        if (!success)
7129            return false;
7130
7131        if (add)
7132            offset_addr = Rn + offset;
7133        else
7134            offset_addr = Rn - offset;
7135
7136        // address = if index then offset_addr else R[n];
7137        if (index)
7138            address = offset_addr;
7139        else
7140            address = Rn;
7141
7142        // R[t] = SignExtend(MemU[address,1], 32);
7143        Register base_reg;
7144        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7145        Register offset_reg;
7146        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7147
7148        EmulateInstruction::Context context;
7149        context.type = eContextRegisterLoad;
7150        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7151
7152        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7153        if (!success)
7154            return false;
7155
7156        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7157        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7158            return false;
7159
7160        // if wback then R[n] = offset_addr;
7161        if (wback)
7162        {
7163            context.type = eContextAdjustBaseRegister;
7164            context.SetAddress (offset_addr);
7165            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7166                return false;
7167        }
7168    }
7169    return true;
7170}
7171
7172// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7173// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7174// pre-indexed addressing.
7175bool
7176EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7177{
7178#if 0
7179    if ConditionPassed() then
7180        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7181        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7182        address = if index then offset_addr else R[n];
7183        data = MemU[address,2];
7184        if wback then R[n] = offset_addr;
7185        if UnalignedSupport() || address<0> = '0' then
7186            R[t] = SignExtend(data, 32);
7187        else // Can only apply before ARMv7
7188            R[t] = bits(32) UNKNOWN;
7189#endif
7190
7191    bool success = false;
7192
7193    if (ConditionPassed(opcode))
7194    {
7195        uint32_t t;
7196        uint32_t n;
7197        uint32_t imm32;
7198        bool index;
7199        bool add;
7200        bool wback;
7201
7202        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7203        switch (encoding)
7204        {
7205            case eEncodingT1:
7206                // if Rn == '1111' then SEE LDRSH (literal);
7207                // if Rt == '1111' then SEE "Unallocated memory hints";
7208                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7209                t = Bits32 (opcode, 15, 12);
7210                n = Bits32 (opcode, 19, 16);
7211                imm32 = Bits32 (opcode, 11, 0);
7212
7213                // index = TRUE; add = TRUE; wback = FALSE;
7214                index = true;
7215                add = true;
7216                wback = false;
7217
7218                // if t == 13 then UNPREDICTABLE;
7219                if (t == 13)
7220                    return false;
7221
7222                break;
7223
7224            case eEncodingT2:
7225                // if Rn == '1111' then SEE LDRSH (literal);
7226                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7227                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7228                // if P == '0' && W == '0' then UNDEFINED;
7229                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7230                  return false;
7231
7232                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7233                t = Bits32 (opcode, 15, 12);
7234                n = Bits32 (opcode, 19, 16);
7235                imm32 = Bits32 (opcode, 7, 0);
7236
7237                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7238                index = BitIsSet (opcode, 10);
7239                add = BitIsSet (opcode, 9);
7240                wback = BitIsSet (opcode, 8);
7241
7242                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7243                if (BadReg (t) || (wback && (n == t)))
7244                    return false;
7245
7246                break;
7247
7248            case eEncodingA1:
7249            {
7250                // if Rn == '1111' then SEE LDRSH (literal);
7251                // if P == '0' && W == '1' then SEE LDRSHT;
7252                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7253                t = Bits32 (opcode, 15, 12);
7254                n = Bits32 (opcode, 19, 16);
7255                uint32_t imm4H = Bits32 (opcode, 11,8);
7256                uint32_t imm4L = Bits32 (opcode, 3, 0);
7257                imm32 = (imm4H << 4) | imm4L;
7258
7259                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7260                index = BitIsSet (opcode, 24);
7261                add = BitIsSet (opcode, 23);
7262                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7263
7264                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7265                if ((t == 15) || (wback && (n == t)))
7266                    return false;
7267
7268                break;
7269            }
7270
7271            default:
7272                return false;
7273        }
7274
7275        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7276        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7277        if (!success)
7278            return false;
7279
7280        addr_t offset_addr;
7281        if (add)
7282            offset_addr = Rn + imm32;
7283        else
7284            offset_addr = Rn - imm32;
7285
7286        // address = if index then offset_addr else R[n];
7287        addr_t address;
7288        if (index)
7289            address = offset_addr;
7290        else
7291            address = Rn;
7292
7293        // data = MemU[address,2];
7294        Register base_reg;
7295        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7296
7297        EmulateInstruction::Context context;
7298        context.type = eContextRegisterLoad;
7299        context.SetRegisterPlusOffset (base_reg, address - Rn);
7300
7301        uint64_t data = MemURead (context, address, 2, 0, &success);
7302        if (!success)
7303            return false;
7304
7305        // if wback then R[n] = offset_addr;
7306        if (wback)
7307        {
7308            context.type = eContextAdjustBaseRegister;
7309            context.SetAddress (offset_addr);
7310            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7311                return false;
7312        }
7313
7314        // if UnalignedSupport() || address<0> = '0' then
7315        if (UnalignedSupport() || BitIsClear (address, 0))
7316        {
7317            // R[t] = SignExtend(data, 32);
7318            int64_t signed_data = llvm::SignExtend64<16>(data);
7319            context.type = eContextRegisterLoad;
7320            context.SetRegisterPlusOffset (base_reg, address - Rn);
7321            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7322                return false;
7323        }
7324        else // Can only apply before ARMv7
7325        {
7326            // R[t] = bits(32) UNKNOWN;
7327            WriteBits32Unknown (t);
7328        }
7329    }
7330    return true;
7331}
7332
7333// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7334// sign-extends it to from a 32-bit word, and writes it to a register.
7335bool
7336EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7337{
7338#if 0
7339    if ConditionPassed() then
7340        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7341        base = Align(PC,4);
7342        address = if add then (base + imm32) else (base - imm32);
7343        data = MemU[address,2];
7344        if UnalignedSupport() || address<0> = '0' then
7345            R[t] = SignExtend(data, 32);
7346        else // Can only apply before ARMv7
7347            R[t] = bits(32) UNKNOWN;
7348#endif
7349
7350    bool success = false;
7351
7352    if (ConditionPassed(opcode))
7353    {
7354        uint32_t t;
7355        uint32_t imm32;
7356        bool add;
7357
7358        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7359        switch (encoding)
7360        {
7361            case eEncodingT1:
7362                // if Rt == '1111' then SEE "Unallocated memory hints";
7363                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7364                t = Bits32  (opcode, 15, 12);
7365                imm32 = Bits32 (opcode, 11, 0);
7366                add = BitIsSet (opcode, 23);
7367
7368                // if t == 13 then UNPREDICTABLE;
7369                if (t == 13)
7370                    return false;
7371
7372                break;
7373
7374            case eEncodingA1:
7375            {
7376                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7377                t = Bits32 (opcode, 15, 12);
7378                uint32_t imm4H = Bits32 (opcode, 11, 8);
7379                uint32_t imm4L = Bits32 (opcode, 3, 0);
7380                imm32 = (imm4H << 4) | imm4L;
7381                add = BitIsSet (opcode, 23);
7382
7383                // if t == 15 then UNPREDICTABLE;
7384                if (t == 15)
7385                    return false;
7386
7387                break;
7388            }
7389            default:
7390                return false;
7391        }
7392
7393        // base = Align(PC,4);
7394        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7395        if (!success)
7396            return false;
7397
7398        uint64_t base = AlignPC (pc_value);
7399
7400        addr_t address;
7401        // address = if add then (base + imm32) else (base - imm32);
7402        if (add)
7403            address = base + imm32;
7404        else
7405            address = base - imm32;
7406
7407        // data = MemU[address,2];
7408        Register base_reg;
7409        base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7410
7411        EmulateInstruction::Context context;
7412        context.type = eContextRegisterLoad;
7413        context.SetRegisterPlusOffset (base_reg, imm32);
7414
7415        uint64_t data = MemURead (context, address, 2, 0, &success);
7416        if (!success)
7417            return false;
7418
7419        // if UnalignedSupport() || address<0> = '0' then
7420        if (UnalignedSupport() || BitIsClear (address, 0))
7421        {
7422            // R[t] = SignExtend(data, 32);
7423            int64_t signed_data = llvm::SignExtend64<16>(data);
7424            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7425                return false;
7426        }
7427        else // Can only apply before ARMv7
7428        {
7429            // R[t] = bits(32) UNKNOWN;
7430            WriteBits32Unknown (t);
7431        }
7432    }
7433    return true;
7434}
7435
7436// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7437// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7438// shifted left by 0, 1, 2, or 3 bits.
7439bool
7440EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7441{
7442#if 0
7443    if ConditionPassed() then
7444        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7445        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7446        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7447        address = if index then offset_addr else R[n];
7448        data = MemU[address,2];
7449        if wback then R[n] = offset_addr;
7450        if UnalignedSupport() || address<0> = '0' then
7451            R[t] = SignExtend(data, 32);
7452        else // Can only apply before ARMv7
7453            R[t] = bits(32) UNKNOWN;
7454#endif
7455
7456    bool success = false;
7457
7458    if (ConditionPassed(opcode))
7459    {
7460        uint32_t t;
7461        uint32_t n;
7462        uint32_t m;
7463        bool index;
7464        bool add;
7465        bool wback;
7466        ARM_ShifterType shift_t;
7467        uint32_t shift_n;
7468
7469        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7470        switch (encoding)
7471        {
7472            case eEncodingT1:
7473                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7474                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7475                t = Bits32 (opcode, 2, 0);
7476                n = Bits32 (opcode, 5, 3);
7477                m = Bits32 (opcode, 8, 6);
7478
7479                // index = TRUE; add = TRUE; wback = FALSE;
7480                index = true;
7481                add = true;
7482                wback = false;
7483
7484                // (shift_t, shift_n) = (SRType_LSL, 0);
7485                shift_t = SRType_LSL;
7486                shift_n = 0;
7487
7488                break;
7489
7490            case eEncodingT2:
7491                // if Rn == '1111' then SEE LDRSH (literal);
7492                // if Rt == '1111' then SEE "Unallocated memory hints";
7493                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7494                t = Bits32 (opcode, 15, 12);
7495                n = Bits32 (opcode, 19, 16);
7496                m = Bits32 (opcode, 3, 0);
7497
7498                // index = TRUE; add = TRUE; wback = FALSE;
7499                index = true;
7500                add = true;
7501                wback = false;
7502
7503                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7504                shift_t = SRType_LSL;
7505                shift_n = Bits32 (opcode, 5, 4);
7506
7507                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7508                if ((t == 13) || BadReg (m))
7509                    return false;
7510
7511                break;
7512
7513            case eEncodingA1:
7514                // if P == '0' && W == '1' then SEE LDRSHT;
7515                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7516                t = Bits32 (opcode, 15, 12);
7517                n = Bits32 (opcode, 19, 16);
7518                m = Bits32 (opcode, 3, 0);
7519
7520                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7521                index = BitIsSet (opcode, 24);
7522                add = BitIsSet (opcode, 23);
7523                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7524
7525                // (shift_t, shift_n) = (SRType_LSL, 0);
7526                shift_t = SRType_LSL;
7527                shift_n = 0;
7528
7529                // if t == 15 || m == 15 then UNPREDICTABLE;
7530                if ((t == 15) || (m == 15))
7531                    return false;
7532
7533                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7534                if (wback && ((n == 15) || (n == t)))
7535                    return false;
7536
7537                break;
7538
7539            default:
7540                break;
7541        }
7542
7543        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7544        if (!success)
7545            return false;
7546
7547        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7548        if (!success)
7549            return false;
7550
7551        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7552        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7553
7554        addr_t offset_addr;
7555        addr_t address;
7556
7557        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7558        if (add)
7559            offset_addr = Rn + offset;
7560        else
7561            offset_addr = Rn - offset;
7562
7563        // address = if index then offset_addr else R[n];
7564        if (index)
7565            address = offset_addr;
7566        else
7567            address = Rn;
7568
7569        // data = MemU[address,2];
7570        Register base_reg;
7571        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7572
7573        Register offset_reg;
7574        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7575
7576        EmulateInstruction::Context context;
7577        context.type = eContextRegisterLoad;
7578        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7579
7580        uint64_t data = MemURead (context, address, 2, 0, &success);
7581        if (!success)
7582            return false;
7583
7584        // if wback then R[n] = offset_addr;
7585        if (wback)
7586        {
7587            context.type = eContextAdjustBaseRegister;
7588            context.SetAddress (offset_addr);
7589            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7590                return false;
7591        }
7592
7593        // if UnalignedSupport() || address<0> = '0' then
7594        if (UnalignedSupport() || BitIsClear (address, 0))
7595        {
7596            // R[t] = SignExtend(data, 32);
7597            context.type = eContextRegisterLoad;
7598            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7599
7600            int64_t signed_data = llvm::SignExtend64<16>(data);
7601            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7602                return false;
7603        }
7604        else // Can only apply before ARMv7
7605        {
7606            // R[t] = bits(32) UNKNOWN;
7607            WriteBits32Unknown (t);
7608        }
7609    }
7610    return true;
7611}
7612
7613// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7614// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7615bool
7616EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7617{
7618#if 0
7619    if ConditionPassed() then
7620        EncodingSpecificOperations();
7621        rotated = ROR(R[m], rotation);
7622        R[d] = SignExtend(rotated<7:0>, 32);
7623#endif
7624
7625    bool success = false;
7626
7627    if (ConditionPassed(opcode))
7628    {
7629        uint32_t d;
7630        uint32_t m;
7631        uint32_t rotation;
7632
7633        // EncodingSpecificOperations();
7634        switch (encoding)
7635        {
7636            case eEncodingT1:
7637                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7638                d = Bits32 (opcode, 2, 0);
7639                m = Bits32 (opcode, 5, 3);
7640                rotation = 0;
7641
7642                break;
7643
7644            case eEncodingT2:
7645                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7646                d = Bits32 (opcode, 11, 8);
7647                m = Bits32 (opcode, 3, 0);
7648                rotation = Bits32 (opcode, 5, 4) << 3;
7649
7650                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7651                if (BadReg (d) || BadReg (m))
7652                    return false;
7653
7654                break;
7655
7656            case eEncodingA1:
7657                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7658                d = Bits32 (opcode, 15, 12);
7659                m = Bits32 (opcode, 3, 0);
7660                rotation = Bits32 (opcode, 11, 10) << 3;
7661
7662                // if d == 15 || m == 15 then UNPREDICTABLE;
7663                if ((d == 15) || (m == 15))
7664                    return false;
7665
7666                break;
7667
7668            default:
7669                return false;
7670        }
7671
7672        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7673        if (!success)
7674            return false;
7675
7676        // rotated = ROR(R[m], rotation);
7677        uint64_t rotated = ROR (Rm, rotation);
7678
7679        // R[d] = SignExtend(rotated<7:0>, 32);
7680        int64_t data = llvm::SignExtend64<8>(rotated);
7681
7682        Register source_reg;
7683        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7684
7685        EmulateInstruction::Context context;
7686        context.type = eContextRegisterLoad;
7687        context.SetRegister (source_reg);
7688
7689        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7690            return false;
7691    }
7692    return true;
7693}
7694
7695// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7696// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7697bool
7698EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7699{
7700#if 0
7701    if ConditionPassed() then
7702        EncodingSpecificOperations();
7703        rotated = ROR(R[m], rotation);
7704        R[d] = SignExtend(rotated<15:0>, 32);
7705#endif
7706
7707    bool success = false;
7708
7709    if (ConditionPassed(opcode))
7710    {
7711        uint32_t d;
7712        uint32_t m;
7713        uint32_t rotation;
7714
7715        // EncodingSpecificOperations();
7716        switch (encoding)
7717        {
7718            case eEncodingT1:
7719                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7720                d = Bits32 (opcode, 2, 0);
7721                m = Bits32 (opcode, 5, 3);
7722                rotation = 0;
7723
7724                break;
7725
7726            case eEncodingT2:
7727                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7728                d = Bits32 (opcode, 11, 8);
7729                m = Bits32 (opcode, 3, 0);
7730                rotation = Bits32 (opcode, 5, 4) << 3;
7731
7732                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7733                if (BadReg (d) || BadReg (m))
7734                    return false;
7735
7736                break;
7737
7738            case eEncodingA1:
7739                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7740                d = Bits32 (opcode, 15, 12);
7741                m = Bits32 (opcode, 3, 0);
7742                rotation = Bits32 (opcode, 11, 10) << 3;
7743
7744                // if d == 15 || m == 15 then UNPREDICTABLE;
7745                if ((d == 15) || (m == 15))
7746                    return false;
7747
7748                break;
7749
7750            default:
7751                return false;
7752        }
7753
7754        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7755        if (!success)
7756            return false;
7757
7758        // rotated = ROR(R[m], rotation);
7759        uint64_t rotated = ROR (Rm, rotation);
7760
7761        // R[d] = SignExtend(rotated<15:0>, 32);
7762        Register source_reg;
7763        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7764
7765        EmulateInstruction::Context context;
7766        context.type = eContextRegisterLoad;
7767        context.SetRegister (source_reg);
7768
7769        int64_t data = llvm::SignExtend64<16> (rotated);
7770        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7771            return false;
7772    }
7773
7774    return true;
7775}
7776
7777// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7778// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7779bool
7780EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7781{
7782#if 0
7783    if ConditionPassed() then
7784        EncodingSpecificOperations();
7785        rotated = ROR(R[m], rotation);
7786        R[d] = ZeroExtend(rotated<7:0>, 32);
7787#endif
7788
7789    bool success = false;
7790
7791    if (ConditionPassed(opcode))
7792    {
7793        uint32_t d;
7794        uint32_t m;
7795        uint32_t rotation;
7796
7797        // EncodingSpecificOperations();
7798        switch (encoding)
7799        {
7800            case eEncodingT1:
7801                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7802                d = Bits32 (opcode, 2, 0);
7803                m = Bits32 (opcode, 5, 3);
7804                rotation = 0;
7805
7806                break;
7807
7808            case eEncodingT2:
7809                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7810                d = Bits32 (opcode, 11, 8);
7811                m = Bits32 (opcode, 3, 0);
7812                  rotation = Bits32 (opcode, 5, 4) << 3;
7813
7814                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7815                if (BadReg (d) || BadReg (m))
7816                  return false;
7817
7818                break;
7819
7820            case eEncodingA1:
7821                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7822                d = Bits32 (opcode, 15, 12);
7823                m = Bits32 (opcode, 3, 0);
7824                rotation = Bits32 (opcode, 11, 10) << 3;
7825
7826                // if d == 15 || m == 15 then UNPREDICTABLE;
7827                if ((d == 15) || (m == 15))
7828                    return false;
7829
7830                break;
7831
7832            default:
7833                return false;
7834        }
7835
7836        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7837        if (!success)
7838            return false;
7839
7840        // rotated = ROR(R[m], rotation);
7841        uint64_t rotated = ROR (Rm, rotation);
7842
7843        // R[d] = ZeroExtend(rotated<7:0>, 32);
7844        Register source_reg;
7845        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7846
7847        EmulateInstruction::Context context;
7848        context.type = eContextRegisterLoad;
7849        context.SetRegister (source_reg);
7850
7851        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7852            return false;
7853    }
7854    return true;
7855}
7856
7857// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
7858// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7859bool
7860EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
7861{
7862#if 0
7863    if ConditionPassed() then
7864        EncodingSpecificOperations();
7865        rotated = ROR(R[m], rotation);
7866        R[d] = ZeroExtend(rotated<15:0>, 32);
7867#endif
7868
7869    bool success = false;
7870
7871    if (ConditionPassed(opcode))
7872    {
7873        uint32_t d;
7874        uint32_t m;
7875        uint32_t rotation;
7876
7877        switch (encoding)
7878        {
7879            case eEncodingT1:
7880                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7881                d = Bits32 (opcode, 2, 0);
7882                m = Bits32 (opcode, 5, 3);
7883                rotation = 0;
7884
7885                break;
7886
7887            case eEncodingT2:
7888                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7889                d = Bits32 (opcode, 11, 8);
7890                m = Bits32 (opcode, 3, 0);
7891                rotation = Bits32 (opcode, 5, 4) << 3;
7892
7893                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7894                if (BadReg (d) || BadReg (m))
7895                  return false;
7896
7897                break;
7898
7899            case eEncodingA1:
7900                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7901                d = Bits32 (opcode, 15, 12);
7902                m = Bits32 (opcode, 3, 0);
7903                rotation = Bits32 (opcode, 11, 10) << 3;
7904
7905                // if d == 15 || m == 15 then UNPREDICTABLE;
7906                if ((d == 15) || (m == 15))
7907                    return false;
7908
7909                break;
7910
7911            default:
7912                return false;
7913        }
7914
7915        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7916        if (!success)
7917            return false;
7918
7919        // rotated = ROR(R[m], rotation);
7920        uint64_t rotated = ROR (Rm, rotation);
7921
7922        // R[d] = ZeroExtend(rotated<15:0>, 32);
7923        Register source_reg;
7924        source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7925
7926        EmulateInstruction::Context context;
7927        context.type = eContextRegisterLoad;
7928        context.SetRegister (source_reg);
7929
7930        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
7931            return false;
7932    }
7933    return true;
7934}
7935
7936// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
7937// word respectively.
7938bool
7939EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
7940{
7941#if 0
7942    if ConditionPassed() then
7943        EncodingSpecificOperations();
7944        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
7945            UNPREDICTABLE;
7946        else
7947            address = if increment then R[n] else R[n]-8;
7948            if wordhigher then address = address+4;
7949            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
7950            BranchWritePC(MemA[address,4]);
7951            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
7952#endif
7953
7954    bool success = false;
7955
7956    if (ConditionPassed(opcode))
7957    {
7958        uint32_t n;
7959        bool wback;
7960        bool increment;
7961        bool wordhigher;
7962
7963        // EncodingSpecificOperations();
7964        switch (encoding)
7965        {
7966            case eEncodingT1:
7967                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
7968                n = Bits32 (opcode, 19, 16);
7969                wback = BitIsSet (opcode, 21);
7970                increment = false;
7971                wordhigher = false;
7972
7973                // if n == 15 then UNPREDICTABLE;
7974                if (n == 15)
7975                    return false;
7976
7977                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7978                if (InITBlock() && !LastInITBlock())
7979                    return false;
7980
7981                break;
7982
7983            case eEncodingT2:
7984                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
7985                n = Bits32 (opcode, 19, 16);
7986                wback = BitIsSet (opcode, 21);
7987                increment = true;
7988                wordhigher = false;
7989
7990                // if n == 15 then UNPREDICTABLE;
7991                if (n == 15)
7992                    return false;
7993
7994                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7995                if (InITBlock() && !LastInITBlock())
7996                    return false;
7997
7998                break;
7999
8000            case eEncodingA1:
8001                // n = UInt(Rn);
8002                n = Bits32 (opcode, 19, 16);
8003
8004                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8005                wback = BitIsSet (opcode, 21);
8006                increment = BitIsSet (opcode, 23);
8007                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8008
8009                // if n == 15 then UNPREDICTABLE;
8010                if (n == 15)
8011                    return false;
8012
8013                break;
8014
8015            default:
8016                return false;
8017        }
8018
8019        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8020        if (!CurrentModeIsPrivileged ())
8021            // UNPREDICTABLE;
8022            return false;
8023        else
8024        {
8025            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8026            if (!success)
8027                return false;
8028
8029            addr_t address;
8030            // address = if increment then R[n] else R[n]-8;
8031            if (increment)
8032                address = Rn;
8033            else
8034                address = Rn - 8;
8035
8036            // if wordhigher then address = address+4;
8037            if (wordhigher)
8038                address = address + 4;
8039
8040            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8041            Register base_reg;
8042            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
8043
8044            EmulateInstruction::Context context;
8045            context.type = eContextReturnFromException;
8046            context.SetRegisterPlusOffset (base_reg, address - Rn);
8047
8048            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8049            if (!success)
8050                return false;
8051
8052            CPSRWriteByInstr (data, 15, true);
8053
8054            // BranchWritePC(MemA[address,4]);
8055            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8056            if (!success)
8057                return false;
8058
8059            BranchWritePC (context, data2);
8060
8061            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8062            if (wback)
8063            {
8064                context.type = eContextAdjustBaseRegister;
8065                if (increment)
8066                {
8067                    context.SetOffset (8);
8068                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8069                        return false;
8070                }
8071                else
8072                {
8073                    context.SetOffset (-8);
8074                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8075                        return false;
8076                }
8077            } // if wback
8078        }
8079    } // if ConditionPassed()
8080    return true;
8081}
8082
8083// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8084// and writes the result to the destination register.  It can optionally update the condition flags based on
8085// the result.
8086bool
8087EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8088{
8089#if 0
8090    // ARM pseudo code...
8091    if ConditionPassed() then
8092        EncodingSpecificOperations();
8093        result = R[n] EOR imm32;
8094        if d == 15 then         // Can only occur for ARM encoding
8095            ALUWritePC(result); // setflags is always FALSE here
8096        else
8097            R[d] = result;
8098            if setflags then
8099                APSR.N = result<31>;
8100                APSR.Z = IsZeroBit(result);
8101                APSR.C = carry;
8102                // APSR.V unchanged
8103#endif
8104
8105    bool success = false;
8106
8107    if (ConditionPassed(opcode))
8108    {
8109        uint32_t Rd, Rn;
8110        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8111        bool setflags;
8112        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8113        switch (encoding)
8114        {
8115        case eEncodingT1:
8116            Rd = Bits32(opcode, 11, 8);
8117            Rn = Bits32(opcode, 19, 16);
8118            setflags = BitIsSet(opcode, 20);
8119            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8120            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8121            if (Rd == 15 && setflags)
8122                return EmulateTEQImm (opcode, eEncodingT1);
8123            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8124                return false;
8125            break;
8126        case eEncodingA1:
8127            Rd = Bits32(opcode, 15, 12);
8128            Rn = Bits32(opcode, 19, 16);
8129            setflags = BitIsSet(opcode, 20);
8130            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8131
8132            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8133            if (Rd == 15 && setflags)
8134                return EmulateSUBSPcLrEtc (opcode, encoding);
8135            break;
8136        default:
8137            return false;
8138        }
8139
8140        // Read the first operand.
8141        uint32_t val1 = ReadCoreReg(Rn, &success);
8142        if (!success)
8143            return false;
8144
8145        uint32_t result = val1 ^ imm32;
8146
8147        EmulateInstruction::Context context;
8148        context.type = EmulateInstruction::eContextImmediate;
8149        context.SetNoArgs ();
8150
8151        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8152            return false;
8153    }
8154    return true;
8155}
8156
8157// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8158// optionally-shifted register value, and writes the result to the destination register.
8159// It can optionally update the condition flags based on the result.
8160bool
8161EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8162{
8163#if 0
8164    // ARM pseudo code...
8165    if ConditionPassed() then
8166        EncodingSpecificOperations();
8167        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8168        result = R[n] EOR shifted;
8169        if d == 15 then         // Can only occur for ARM encoding
8170            ALUWritePC(result); // setflags is always FALSE here
8171        else
8172            R[d] = result;
8173            if setflags then
8174                APSR.N = result<31>;
8175                APSR.Z = IsZeroBit(result);
8176                APSR.C = carry;
8177                // APSR.V unchanged
8178#endif
8179
8180    bool success = false;
8181
8182    if (ConditionPassed(opcode))
8183    {
8184        uint32_t Rd, Rn, Rm;
8185        ARM_ShifterType shift_t;
8186        uint32_t shift_n; // the shift applied to the value read from Rm
8187        bool setflags;
8188        uint32_t carry;
8189        switch (encoding)
8190        {
8191        case eEncodingT1:
8192            Rd = Rn = Bits32(opcode, 2, 0);
8193            Rm = Bits32(opcode, 5, 3);
8194            setflags = !InITBlock();
8195            shift_t = SRType_LSL;
8196            shift_n = 0;
8197            break;
8198        case eEncodingT2:
8199            Rd = Bits32(opcode, 11, 8);
8200            Rn = Bits32(opcode, 19, 16);
8201            Rm = Bits32(opcode, 3, 0);
8202            setflags = BitIsSet(opcode, 20);
8203            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8204            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8205            if (Rd == 15 && setflags)
8206                return EmulateTEQReg (opcode, eEncodingT1);
8207            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8208                return false;
8209            break;
8210        case eEncodingA1:
8211            Rd = Bits32(opcode, 15, 12);
8212            Rn = Bits32(opcode, 19, 16);
8213            Rm = Bits32(opcode, 3, 0);
8214            setflags = BitIsSet(opcode, 20);
8215            shift_n = DecodeImmShiftARM(opcode, shift_t);
8216
8217            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8218            if (Rd == 15 && setflags)
8219                return EmulateSUBSPcLrEtc (opcode, encoding);
8220            break;
8221        default:
8222            return false;
8223        }
8224
8225        // Read the first operand.
8226        uint32_t val1 = ReadCoreReg(Rn, &success);
8227        if (!success)
8228            return false;
8229
8230        // Read the second operand.
8231        uint32_t val2 = ReadCoreReg(Rm, &success);
8232        if (!success)
8233            return false;
8234
8235        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8236        uint32_t result = val1 ^ shifted;
8237
8238        EmulateInstruction::Context context;
8239        context.type = EmulateInstruction::eContextImmediate;
8240        context.SetNoArgs ();
8241
8242        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8243            return false;
8244    }
8245    return true;
8246}
8247
8248// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8249// writes the result to the destination register.  It can optionally update the condition flags based
8250// on the result.
8251bool
8252EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8253{
8254#if 0
8255    // ARM pseudo code...
8256    if ConditionPassed() then
8257        EncodingSpecificOperations();
8258        result = R[n] OR imm32;
8259        if d == 15 then         // Can only occur for ARM encoding
8260            ALUWritePC(result); // setflags is always FALSE here
8261        else
8262            R[d] = result;
8263            if setflags then
8264                APSR.N = result<31>;
8265                APSR.Z = IsZeroBit(result);
8266                APSR.C = carry;
8267                // APSR.V unchanged
8268#endif
8269
8270    bool success = false;
8271
8272    if (ConditionPassed(opcode))
8273    {
8274        uint32_t Rd, Rn;
8275        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8276        bool setflags;
8277        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8278        switch (encoding)
8279        {
8280        case eEncodingT1:
8281            Rd = Bits32(opcode, 11, 8);
8282            Rn = Bits32(opcode, 19, 16);
8283            setflags = BitIsSet(opcode, 20);
8284            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8285            // if Rn == '1111' then SEE MOV (immediate);
8286            if (Rn == 15)
8287                return EmulateMOVRdImm (opcode, eEncodingT2);
8288            if (BadReg(Rd) || Rn == 13)
8289                return false;
8290            break;
8291        case eEncodingA1:
8292            Rd = Bits32(opcode, 15, 12);
8293            Rn = Bits32(opcode, 19, 16);
8294            setflags = BitIsSet(opcode, 20);
8295            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8296
8297            if (Rd == 15 && setflags)
8298                return EmulateSUBSPcLrEtc (opcode, encoding);
8299            break;
8300        default:
8301            return false;
8302        }
8303
8304        // Read the first operand.
8305        uint32_t val1 = ReadCoreReg(Rn, &success);
8306        if (!success)
8307            return false;
8308
8309        uint32_t result = val1 | imm32;
8310
8311        EmulateInstruction::Context context;
8312        context.type = EmulateInstruction::eContextImmediate;
8313        context.SetNoArgs ();
8314
8315        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8316            return false;
8317    }
8318    return true;
8319}
8320
8321// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8322// value, and writes the result to the destination register.  It can optionally update the condition flags based
8323// on the result.
8324bool
8325EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8326{
8327#if 0
8328    // ARM pseudo code...
8329    if ConditionPassed() then
8330        EncodingSpecificOperations();
8331        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8332        result = R[n] OR shifted;
8333        if d == 15 then         // Can only occur for ARM encoding
8334            ALUWritePC(result); // setflags is always FALSE here
8335        else
8336            R[d] = result;
8337            if setflags then
8338                APSR.N = result<31>;
8339                APSR.Z = IsZeroBit(result);
8340                APSR.C = carry;
8341                // APSR.V unchanged
8342#endif
8343
8344    bool success = false;
8345
8346    if (ConditionPassed(opcode))
8347    {
8348        uint32_t Rd, Rn, Rm;
8349        ARM_ShifterType shift_t;
8350        uint32_t shift_n; // the shift applied to the value read from Rm
8351        bool setflags;
8352        uint32_t carry;
8353        switch (encoding)
8354        {
8355        case eEncodingT1:
8356            Rd = Rn = Bits32(opcode, 2, 0);
8357            Rm = Bits32(opcode, 5, 3);
8358            setflags = !InITBlock();
8359            shift_t = SRType_LSL;
8360            shift_n = 0;
8361            break;
8362        case eEncodingT2:
8363            Rd = Bits32(opcode, 11, 8);
8364            Rn = Bits32(opcode, 19, 16);
8365            Rm = Bits32(opcode, 3, 0);
8366            setflags = BitIsSet(opcode, 20);
8367            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8368            // if Rn == '1111' then SEE MOV (register);
8369            if (Rn == 15)
8370                return EmulateMOVRdRm (opcode, eEncodingT3);
8371            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8372                return false;
8373            break;
8374        case eEncodingA1:
8375            Rd = Bits32(opcode, 15, 12);
8376            Rn = Bits32(opcode, 19, 16);
8377            Rm = Bits32(opcode, 3, 0);
8378            setflags = BitIsSet(opcode, 20);
8379            shift_n = DecodeImmShiftARM(opcode, shift_t);
8380
8381            if (Rd == 15 && setflags)
8382                return EmulateSUBSPcLrEtc (opcode, encoding);
8383            break;
8384        default:
8385            return false;
8386        }
8387
8388        // Read the first operand.
8389        uint32_t val1 = ReadCoreReg(Rn, &success);
8390        if (!success)
8391            return false;
8392
8393        // Read the second operand.
8394        uint32_t val2 = ReadCoreReg(Rm, &success);
8395        if (!success)
8396            return false;
8397
8398        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8399        uint32_t result = val1 | shifted;
8400
8401        EmulateInstruction::Context context;
8402        context.type = EmulateInstruction::eContextImmediate;
8403        context.SetNoArgs ();
8404
8405        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8406            return false;
8407    }
8408    return true;
8409}
8410
8411// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8412// the destination register. It can optionally update the condition flags based on the result.
8413bool
8414EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8415{
8416#if 0
8417    // ARM pseudo code...
8418    if ConditionPassed() then
8419        EncodingSpecificOperations();
8420        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8421        if d == 15 then         // Can only occur for ARM encoding
8422            ALUWritePC(result); // setflags is always FALSE here
8423        else
8424            R[d] = result;
8425            if setflags then
8426                APSR.N = result<31>;
8427                APSR.Z = IsZeroBit(result);
8428                APSR.C = carry;
8429                APSR.V = overflow;
8430#endif
8431
8432    bool success = false;
8433
8434    uint32_t Rd; // the destination register
8435    uint32_t Rn; // the first operand
8436    bool setflags;
8437    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8438    switch (encoding) {
8439    case eEncodingT1:
8440        Rd = Bits32(opcode, 2, 0);
8441        Rn = Bits32(opcode, 5, 3);
8442        setflags = !InITBlock();
8443        imm32 = 0;
8444        break;
8445    case eEncodingT2:
8446        Rd = Bits32(opcode, 11, 8);
8447        Rn = Bits32(opcode, 19, 16);
8448        setflags = BitIsSet(opcode, 20);
8449        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8450        if (BadReg(Rd) || BadReg(Rn))
8451            return false;
8452        break;
8453    case eEncodingA1:
8454        Rd = Bits32(opcode, 15, 12);
8455        Rn = Bits32(opcode, 19, 16);
8456        setflags = BitIsSet(opcode, 20);
8457        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8458
8459        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8460        if (Rd == 15 && setflags)
8461            return EmulateSUBSPcLrEtc (opcode, encoding);
8462        break;
8463    default:
8464        return false;
8465    }
8466    // Read the register value from the operand register Rn.
8467    uint32_t reg_val = ReadCoreReg(Rn, &success);
8468    if (!success)
8469        return false;
8470
8471    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8472
8473    EmulateInstruction::Context context;
8474    context.type = EmulateInstruction::eContextImmediate;
8475    context.SetNoArgs ();
8476
8477    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8478        return false;
8479
8480    return true;
8481}
8482
8483// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8484// result to the destination register. It can optionally update the condition flags based on the result.
8485bool
8486EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8487{
8488#if 0
8489    // ARM pseudo code...
8490    if ConditionPassed() then
8491        EncodingSpecificOperations();
8492        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8493        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8494        if d == 15 then         // Can only occur for ARM encoding
8495            ALUWritePC(result); // setflags is always FALSE here
8496        else
8497            R[d] = result;
8498            if setflags then
8499                APSR.N = result<31>;
8500                APSR.Z = IsZeroBit(result);
8501                APSR.C = carry;
8502                APSR.V = overflow;
8503#endif
8504
8505    bool success = false;
8506
8507    uint32_t Rd; // the destination register
8508    uint32_t Rn; // the first operand
8509    uint32_t Rm; // the second operand
8510    bool setflags;
8511    ARM_ShifterType shift_t;
8512    uint32_t shift_n; // the shift applied to the value read from Rm
8513    switch (encoding) {
8514    case eEncodingT1:
8515        Rd = Bits32(opcode, 11, 8);
8516        Rn = Bits32(opcode, 19, 16);
8517        Rm = Bits32(opcode, 3, 0);
8518        setflags = BitIsSet(opcode, 20);
8519        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8520        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8521        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8522            return false;
8523        break;
8524    case eEncodingA1:
8525        Rd = Bits32(opcode, 15, 12);
8526        Rn = Bits32(opcode, 19, 16);
8527        Rm = Bits32(opcode, 3, 0);
8528        setflags = BitIsSet(opcode, 20);
8529        shift_n = DecodeImmShiftARM(opcode, shift_t);
8530
8531        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8532        if (Rd == 15 && setflags)
8533            return EmulateSUBSPcLrEtc (opcode, encoding);
8534        break;
8535    default:
8536        return false;
8537    }
8538    // Read the register value from register Rn.
8539    uint32_t val1 = ReadCoreReg(Rn, &success);
8540    if (!success)
8541        return false;
8542
8543    // Read the register value from register Rm.
8544    uint32_t val2 = ReadCoreReg(Rm, &success);
8545    if (!success)
8546        return false;
8547
8548    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8549    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8550
8551    EmulateInstruction::Context context;
8552    context.type = EmulateInstruction::eContextImmediate;
8553    context.SetNoArgs();
8554    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8555        return false;
8556
8557    return true;
8558}
8559
8560// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8561// an immediate value, and writes the result to the destination register. It can optionally update the condition
8562// flags based on the result.
8563bool
8564EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8565{
8566#if 0
8567    // ARM pseudo code...
8568    if ConditionPassed() then
8569        EncodingSpecificOperations();
8570        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8571        if d == 15 then
8572            ALUWritePC(result); // setflags is always FALSE here
8573        else
8574            R[d] = result;
8575            if setflags then
8576                APSR.N = result<31>;
8577                APSR.Z = IsZeroBit(result);
8578                APSR.C = carry;
8579                APSR.V = overflow;
8580#endif
8581
8582    bool success = false;
8583
8584    uint32_t Rd; // the destination register
8585    uint32_t Rn; // the first operand
8586    bool setflags;
8587    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8588    switch (encoding) {
8589    case eEncodingA1:
8590        Rd = Bits32(opcode, 15, 12);
8591        Rn = Bits32(opcode, 19, 16);
8592        setflags = BitIsSet(opcode, 20);
8593        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8594
8595        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8596        if (Rd == 15 && setflags)
8597            return EmulateSUBSPcLrEtc  (opcode, encoding);
8598        break;
8599    default:
8600        return false;
8601    }
8602    // Read the register value from the operand register Rn.
8603    uint32_t reg_val = ReadCoreReg(Rn, &success);
8604    if (!success)
8605        return false;
8606
8607    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8608
8609    EmulateInstruction::Context context;
8610    context.type = EmulateInstruction::eContextImmediate;
8611    context.SetNoArgs ();
8612
8613    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8614        return false;
8615
8616    return true;
8617}
8618
8619// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8620// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8621// condition flags based on the result.
8622bool
8623EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8624{
8625#if 0
8626    // ARM pseudo code...
8627    if ConditionPassed() then
8628        EncodingSpecificOperations();
8629        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8630        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8631        if d == 15 then
8632            ALUWritePC(result); // setflags is always FALSE here
8633        else
8634            R[d] = result;
8635            if setflags then
8636                APSR.N = result<31>;
8637                APSR.Z = IsZeroBit(result);
8638                APSR.C = carry;
8639                APSR.V = overflow;
8640#endif
8641
8642    bool success = false;
8643
8644    uint32_t Rd; // the destination register
8645    uint32_t Rn; // the first operand
8646    uint32_t Rm; // the second operand
8647    bool setflags;
8648    ARM_ShifterType shift_t;
8649    uint32_t shift_n; // the shift applied to the value read from Rm
8650    switch (encoding) {
8651    case eEncodingA1:
8652        Rd = Bits32(opcode, 15, 12);
8653        Rn = Bits32(opcode, 19, 16);
8654        Rm = Bits32(opcode, 3, 0);
8655        setflags = BitIsSet(opcode, 20);
8656        shift_n = DecodeImmShiftARM(opcode, shift_t);
8657
8658        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8659        if (Rd == 15 && setflags)
8660            return EmulateSUBSPcLrEtc (opcode, encoding);
8661        break;
8662    default:
8663        return false;
8664    }
8665    // Read the register value from register Rn.
8666    uint32_t val1 = ReadCoreReg(Rn, &success);
8667    if (!success)
8668        return false;
8669
8670    // Read the register value from register Rm.
8671    uint32_t val2 = ReadCoreReg(Rm, &success);
8672    if (!success)
8673        return false;
8674
8675    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8676    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8677
8678    EmulateInstruction::Context context;
8679    context.type = EmulateInstruction::eContextImmediate;
8680    context.SetNoArgs();
8681    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8682        return false;
8683
8684    return true;
8685}
8686
8687// Subtract with Carry (immediate) subtracts an immediate value and the value of
8688// NOT (Carry flag) from a register value, and writes the result to the destination register.
8689// It can optionally update the condition flags based on the result.
8690bool
8691EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8692{
8693#if 0
8694    // ARM pseudo code...
8695    if ConditionPassed() then
8696        EncodingSpecificOperations();
8697        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8698        if d == 15 then         // Can only occur for ARM encoding
8699            ALUWritePC(result); // setflags is always FALSE here
8700        else
8701            R[d] = result;
8702            if setflags then
8703                APSR.N = result<31>;
8704                APSR.Z = IsZeroBit(result);
8705                APSR.C = carry;
8706                APSR.V = overflow;
8707#endif
8708
8709    bool success = false;
8710
8711    uint32_t Rd; // the destination register
8712    uint32_t Rn; // the first operand
8713    bool setflags;
8714    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8715    switch (encoding) {
8716    case eEncodingT1:
8717        Rd = Bits32(opcode, 11, 8);
8718        Rn = Bits32(opcode, 19, 16);
8719        setflags = BitIsSet(opcode, 20);
8720        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8721        if (BadReg(Rd) || BadReg(Rn))
8722            return false;
8723        break;
8724    case eEncodingA1:
8725        Rd = Bits32(opcode, 15, 12);
8726        Rn = Bits32(opcode, 19, 16);
8727        setflags = BitIsSet(opcode, 20);
8728        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8729
8730        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8731        if (Rd == 15 && setflags)
8732            return EmulateSUBSPcLrEtc (opcode, encoding);
8733        break;
8734    default:
8735        return false;
8736    }
8737    // Read the register value from the operand register Rn.
8738    uint32_t reg_val = ReadCoreReg(Rn, &success);
8739    if (!success)
8740        return false;
8741
8742    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8743
8744    EmulateInstruction::Context context;
8745    context.type = EmulateInstruction::eContextImmediate;
8746    context.SetNoArgs ();
8747
8748    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8749        return false;
8750
8751    return true;
8752}
8753
8754// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8755// NOT (Carry flag) from a register value, and writes the result to the destination register.
8756// It can optionally update the condition flags based on the result.
8757bool
8758EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8759{
8760#if 0
8761    // ARM pseudo code...
8762    if ConditionPassed() then
8763        EncodingSpecificOperations();
8764        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8765        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8766        if d == 15 then         // Can only occur for ARM encoding
8767            ALUWritePC(result); // setflags is always FALSE here
8768        else
8769            R[d] = result;
8770            if setflags then
8771                APSR.N = result<31>;
8772                APSR.Z = IsZeroBit(result);
8773                APSR.C = carry;
8774                APSR.V = overflow;
8775#endif
8776
8777    bool success = false;
8778
8779    uint32_t Rd; // the destination register
8780    uint32_t Rn; // the first operand
8781    uint32_t Rm; // the second operand
8782    bool setflags;
8783    ARM_ShifterType shift_t;
8784    uint32_t shift_n; // the shift applied to the value read from Rm
8785    switch (encoding) {
8786    case eEncodingT1:
8787        Rd = Rn = Bits32(opcode, 2, 0);
8788        Rm = Bits32(opcode, 5, 3);
8789        setflags = !InITBlock();
8790        shift_t = SRType_LSL;
8791        shift_n = 0;
8792        break;
8793    case eEncodingT2:
8794        Rd = Bits32(opcode, 11, 8);
8795        Rn = Bits32(opcode, 19, 16);
8796        Rm = Bits32(opcode, 3, 0);
8797        setflags = BitIsSet(opcode, 20);
8798        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8799        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8800            return false;
8801        break;
8802    case eEncodingA1:
8803        Rd = Bits32(opcode, 15, 12);
8804        Rn = Bits32(opcode, 19, 16);
8805        Rm = Bits32(opcode, 3, 0);
8806        setflags = BitIsSet(opcode, 20);
8807        shift_n = DecodeImmShiftARM(opcode, shift_t);
8808
8809        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8810        if (Rd == 15 && setflags)
8811            return EmulateSUBSPcLrEtc (opcode, encoding);
8812        break;
8813    default:
8814        return false;
8815    }
8816    // Read the register value from register Rn.
8817    uint32_t val1 = ReadCoreReg(Rn, &success);
8818    if (!success)
8819        return false;
8820
8821    // Read the register value from register Rm.
8822    uint32_t val2 = ReadCoreReg(Rm, &success);
8823    if (!success)
8824        return false;
8825
8826    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8827    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8828
8829    EmulateInstruction::Context context;
8830    context.type = EmulateInstruction::eContextImmediate;
8831    context.SetNoArgs();
8832    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8833        return false;
8834
8835    return true;
8836}
8837
8838// This instruction subtracts an immediate value from a register value, and writes the result
8839// to the destination register.  It can optionally update the condition flags based on the result.
8840bool
8841EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
8842{
8843#if 0
8844    // ARM pseudo code...
8845    if ConditionPassed() then
8846        EncodingSpecificOperations();
8847        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8848        R[d] = result;
8849        if setflags then
8850            APSR.N = result<31>;
8851            APSR.Z = IsZeroBit(result);
8852            APSR.C = carry;
8853            APSR.V = overflow;
8854#endif
8855
8856    bool success = false;
8857
8858    uint32_t Rd; // the destination register
8859    uint32_t Rn; // the first operand
8860    bool setflags;
8861    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8862    switch (encoding) {
8863    case eEncodingT1:
8864        Rd = Bits32(opcode, 2, 0);
8865        Rn = Bits32(opcode, 5, 3);
8866        setflags = !InITBlock();
8867        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
8868        break;
8869    case eEncodingT2:
8870        Rd = Rn = Bits32(opcode, 10, 8);
8871        setflags = !InITBlock();
8872        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
8873        break;
8874    case eEncodingT3:
8875        Rd = Bits32(opcode, 11, 8);
8876        Rn = Bits32(opcode, 19, 16);
8877        setflags = BitIsSet(opcode, 20);
8878        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8879
8880        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
8881        if (Rd == 15 && setflags)
8882            return EmulateCMPImm (opcode, eEncodingT2);
8883
8884        // if Rn == '1101' then SEE SUB (SP minus immediate);
8885        if (Rn == 13)
8886            return EmulateSUBSPImm (opcode, eEncodingT2);
8887
8888        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
8889        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
8890            return false;
8891        break;
8892    case eEncodingT4:
8893        Rd = Bits32(opcode, 11, 8);
8894        Rn = Bits32(opcode, 19, 16);
8895        setflags = BitIsSet(opcode, 20);
8896        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
8897
8898        // if Rn == '1111' then SEE ADR;
8899        if (Rn == 15)
8900            return EmulateADR (opcode, eEncodingT2);
8901
8902        // if Rn == '1101' then SEE SUB (SP minus immediate);
8903        if (Rn == 13)
8904            return EmulateSUBSPImm (opcode, eEncodingT3);
8905
8906        if (BadReg(Rd))
8907            return false;
8908        break;
8909    default:
8910        return false;
8911    }
8912    // Read the register value from the operand register Rn.
8913    uint32_t reg_val = ReadCoreReg(Rn, &success);
8914    if (!success)
8915        return false;
8916
8917    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8918
8919    EmulateInstruction::Context context;
8920    context.type = EmulateInstruction::eContextImmediate;
8921    context.SetNoArgs ();
8922
8923    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8924        return false;
8925
8926    return true;
8927}
8928
8929// This instruction subtracts an immediate value from a register value, and writes the result
8930// to the destination register.  It can optionally update the condition flags based on the result.
8931bool
8932EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
8933{
8934#if 0
8935    // ARM pseudo code...
8936    if ConditionPassed() then
8937        EncodingSpecificOperations();
8938        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8939        if d == 15 then
8940            ALUWritePC(result); // setflags is always FALSE here
8941        else
8942            R[d] = result;
8943            if setflags then
8944                APSR.N = result<31>;
8945                APSR.Z = IsZeroBit(result);
8946                APSR.C = carry;
8947                APSR.V = overflow;
8948#endif
8949
8950    bool success = false;
8951
8952    uint32_t Rd; // the destination register
8953    uint32_t Rn; // the first operand
8954    bool setflags;
8955    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8956    switch (encoding) {
8957    case eEncodingA1:
8958        Rd = Bits32(opcode, 15, 12);
8959        Rn = Bits32(opcode, 19, 16);
8960        setflags = BitIsSet(opcode, 20);
8961        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8962
8963        // if Rn == '1111' && S == '0' then SEE ADR;
8964        if (Rn == 15 && !setflags)
8965            return EmulateADR (opcode, eEncodingA2);
8966
8967        // if Rn == '1101' then SEE SUB (SP minus immediate);
8968        if (Rn == 13)
8969            return EmulateSUBSPImm (opcode, eEncodingA1);
8970
8971        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8972        if (Rd == 15 && setflags)
8973            return EmulateSUBSPcLrEtc (opcode, encoding);
8974        break;
8975    default:
8976        return false;
8977    }
8978    // Read the register value from the operand register Rn.
8979    uint32_t reg_val = ReadCoreReg(Rn, &success);
8980    if (!success)
8981        return false;
8982
8983    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8984
8985    EmulateInstruction::Context context;
8986    context.type = EmulateInstruction::eContextImmediate;
8987    context.SetNoArgs ();
8988
8989    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8990        return false;
8991
8992    return true;
8993}
8994
8995// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
8996// immediate value.  It updates the condition flags based on the result, and discards the result.
8997bool
8998EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
8999{
9000#if 0
9001    // ARM pseudo code...
9002    if ConditionPassed() then
9003        EncodingSpecificOperations();
9004        result = R[n] EOR imm32;
9005        APSR.N = result<31>;
9006        APSR.Z = IsZeroBit(result);
9007        APSR.C = carry;
9008        // APSR.V unchanged
9009#endif
9010
9011    bool success = false;
9012
9013    if (ConditionPassed(opcode))
9014    {
9015        uint32_t Rn;
9016        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9017        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9018        switch (encoding)
9019        {
9020        case eEncodingT1:
9021            Rn = Bits32(opcode, 19, 16);
9022            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9023            if (BadReg(Rn))
9024                return false;
9025            break;
9026        case eEncodingA1:
9027            Rn = Bits32(opcode, 19, 16);
9028            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9029            break;
9030        default:
9031            return false;
9032        }
9033
9034        // Read the first operand.
9035        uint32_t val1 = ReadCoreReg(Rn, &success);
9036        if (!success)
9037            return false;
9038
9039        uint32_t result = val1 ^ imm32;
9040
9041        EmulateInstruction::Context context;
9042        context.type = EmulateInstruction::eContextImmediate;
9043        context.SetNoArgs ();
9044
9045        if (!WriteFlags(context, result, carry))
9046            return false;
9047    }
9048    return true;
9049}
9050
9051// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9052// optionally-shifted register value.  It updates the condition flags based on the result, and discards
9053// the result.
9054bool
9055EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9056{
9057#if 0
9058    // ARM pseudo code...
9059    if ConditionPassed() then
9060        EncodingSpecificOperations();
9061        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9062        result = R[n] EOR shifted;
9063        APSR.N = result<31>;
9064        APSR.Z = IsZeroBit(result);
9065        APSR.C = carry;
9066        // APSR.V unchanged
9067#endif
9068
9069    bool success = false;
9070
9071    if (ConditionPassed(opcode))
9072    {
9073        uint32_t Rn, Rm;
9074        ARM_ShifterType shift_t;
9075        uint32_t shift_n; // the shift applied to the value read from Rm
9076        uint32_t carry;
9077        switch (encoding)
9078        {
9079        case eEncodingT1:
9080            Rn = Bits32(opcode, 19, 16);
9081            Rm = Bits32(opcode, 3, 0);
9082            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9083            if (BadReg(Rn) || BadReg(Rm))
9084                return false;
9085            break;
9086        case eEncodingA1:
9087            Rn = Bits32(opcode, 19, 16);
9088            Rm = Bits32(opcode, 3, 0);
9089            shift_n = DecodeImmShiftARM(opcode, shift_t);
9090            break;
9091        default:
9092            return false;
9093        }
9094
9095        // Read the first operand.
9096        uint32_t val1 = ReadCoreReg(Rn, &success);
9097        if (!success)
9098            return false;
9099
9100        // Read the second operand.
9101        uint32_t val2 = ReadCoreReg(Rm, &success);
9102        if (!success)
9103            return false;
9104
9105        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9106        uint32_t result = val1 ^ shifted;
9107
9108        EmulateInstruction::Context context;
9109        context.type = EmulateInstruction::eContextImmediate;
9110        context.SetNoArgs ();
9111
9112        if (!WriteFlags(context, result, carry))
9113            return false;
9114    }
9115    return true;
9116}
9117
9118// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9119// It updates the condition flags based on the result, and discards the result.
9120bool
9121EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9122{
9123#if 0
9124    // ARM pseudo code...
9125    if ConditionPassed() then
9126        EncodingSpecificOperations();
9127        result = R[n] AND imm32;
9128        APSR.N = result<31>;
9129        APSR.Z = IsZeroBit(result);
9130        APSR.C = carry;
9131        // APSR.V unchanged
9132#endif
9133
9134    bool success = false;
9135
9136    if (ConditionPassed(opcode))
9137    {
9138        uint32_t Rn;
9139        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9140        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9141        switch (encoding)
9142        {
9143        case eEncodingT1:
9144            Rn = Bits32(opcode, 19, 16);
9145            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9146            if (BadReg(Rn))
9147                return false;
9148            break;
9149        case eEncodingA1:
9150            Rn = Bits32(opcode, 19, 16);
9151            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9152            break;
9153        default:
9154            return false;
9155        }
9156
9157        // Read the first operand.
9158        uint32_t val1 = ReadCoreReg(Rn, &success);
9159        if (!success)
9160            return false;
9161
9162        uint32_t result = val1 & imm32;
9163
9164        EmulateInstruction::Context context;
9165        context.type = EmulateInstruction::eContextImmediate;
9166        context.SetNoArgs ();
9167
9168        if (!WriteFlags(context, result, carry))
9169            return false;
9170    }
9171    return true;
9172}
9173
9174// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9175// It updates the condition flags based on the result, and discards the result.
9176bool
9177EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9178{
9179#if 0
9180    // ARM pseudo code...
9181    if ConditionPassed() then
9182        EncodingSpecificOperations();
9183        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9184        result = R[n] AND shifted;
9185        APSR.N = result<31>;
9186        APSR.Z = IsZeroBit(result);
9187        APSR.C = carry;
9188        // APSR.V unchanged
9189#endif
9190
9191    bool success = false;
9192
9193    if (ConditionPassed(opcode))
9194    {
9195        uint32_t Rn, Rm;
9196        ARM_ShifterType shift_t;
9197        uint32_t shift_n; // the shift applied to the value read from Rm
9198        uint32_t carry;
9199        switch (encoding)
9200        {
9201        case eEncodingT1:
9202            Rn = Bits32(opcode, 2, 0);
9203            Rm = Bits32(opcode, 5, 3);
9204            shift_t = SRType_LSL;
9205            shift_n = 0;
9206            break;
9207        case eEncodingT2:
9208            Rn = Bits32(opcode, 19, 16);
9209            Rm = Bits32(opcode, 3, 0);
9210            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9211            if (BadReg(Rn) || BadReg(Rm))
9212                return false;
9213            break;
9214        case eEncodingA1:
9215            Rn = Bits32(opcode, 19, 16);
9216            Rm = Bits32(opcode, 3, 0);
9217            shift_n = DecodeImmShiftARM(opcode, shift_t);
9218            break;
9219        default:
9220            return false;
9221        }
9222
9223        // Read the first operand.
9224        uint32_t val1 = ReadCoreReg(Rn, &success);
9225        if (!success)
9226            return false;
9227
9228        // Read the second operand.
9229        uint32_t val2 = ReadCoreReg(Rm, &success);
9230        if (!success)
9231            return false;
9232
9233        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9234        uint32_t result = val1 & shifted;
9235
9236        EmulateInstruction::Context context;
9237        context.type = EmulateInstruction::eContextImmediate;
9238        context.SetNoArgs ();
9239
9240        if (!WriteFlags(context, result, carry))
9241            return false;
9242    }
9243    return true;
9244}
9245
9246// A8.6.216 SUB (SP minus register)
9247bool
9248EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9249{
9250#if 0
9251    if ConditionPassed() then
9252        EncodingSpecificOperations();
9253        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9254        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9255        if d == 15 then // Can only occur for ARM encoding
9256            ALUWritePC(result); // setflags is always FALSE here
9257        else
9258            R[d] = result;
9259            if setflags then
9260                APSR.N = result<31>;
9261                APSR.Z = IsZeroBit(result);
9262                APSR.C = carry;
9263                APSR.V = overflow;
9264#endif
9265
9266    bool success = false;
9267
9268    if (ConditionPassed(opcode))
9269    {
9270        uint32_t d;
9271        uint32_t m;
9272        bool setflags;
9273        ARM_ShifterType shift_t;
9274        uint32_t shift_n;
9275
9276        switch (encoding)
9277        {
9278            case eEncodingT1:
9279                // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9280                d = Bits32 (opcode, 11, 8);
9281                m = Bits32 (opcode, 3, 0);
9282                setflags = BitIsSet (opcode, 20);
9283
9284                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9285                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9286
9287                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9288                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9289                    return false;
9290
9291                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9292                if ((d == 15) || BadReg (m))
9293                    return false;
9294                break;
9295
9296            case eEncodingA1:
9297                // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9298                d = Bits32 (opcode, 15, 12);
9299                m = Bits32 (opcode, 3, 0);
9300                setflags = BitIsSet (opcode, 20);
9301
9302                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9303                if (d == 15 && setflags)
9304                    EmulateSUBSPcLrEtc (opcode, encoding);
9305
9306                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9307                shift_n = DecodeImmShiftARM (opcode, shift_t);
9308                break;
9309
9310            default:
9311                return false;
9312        }
9313
9314        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9315        uint32_t Rm = ReadCoreReg (m, &success);
9316        if (!success)
9317            return false;
9318
9319        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9320
9321        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9322        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9323        if (!success)
9324            return false;
9325
9326        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9327
9328        EmulateInstruction::Context context;
9329        context.type = eContextSubtraction;
9330        Register sp_reg;
9331        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
9332        Register dwarf_reg;
9333        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9334        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9335
9336        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9337            return false;
9338    }
9339    return true;
9340}
9341
9342
9343// A8.6.7 ADD (register-shifted register)
9344bool
9345EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9346{
9347#if 0
9348    if ConditionPassed() then
9349        EncodingSpecificOperations();
9350        shift_n = UInt(R[s]<7:0>);
9351        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9352        (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9353        R[d] = result;
9354        if setflags then
9355            APSR.N = result<31>;
9356            APSR.Z = IsZeroBit(result);
9357            APSR.C = carry;
9358            APSR.V = overflow;
9359#endif
9360
9361    bool success = false;
9362
9363    if (ConditionPassed(opcode))
9364    {
9365        uint32_t d;
9366        uint32_t n;
9367        uint32_t m;
9368        uint32_t s;
9369        bool setflags;
9370        ARM_ShifterType shift_t;
9371
9372        switch (encoding)
9373        {
9374            case eEncodingA1:
9375                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9376                d = Bits32 (opcode, 15, 12);
9377                n = Bits32 (opcode, 19, 16);
9378                m = Bits32 (opcode, 3, 0);
9379                s = Bits32 (opcode, 11, 8);
9380
9381                // setflags = (S == ‘1’); shift_t = DecodeRegShift(type);
9382                setflags = BitIsSet (opcode, 20);
9383                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9384
9385                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9386                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9387                    return false;
9388                break;
9389
9390            default:
9391                return false;
9392        }
9393
9394        // shift_n = UInt(R[s]<7:0>);
9395        uint32_t Rs = ReadCoreReg (s, &success);
9396        if (!success)
9397            return false;
9398
9399        uint32_t shift_n = Bits32 (Rs, 7, 0);
9400
9401        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9402        uint32_t Rm = ReadCoreReg (m, &success);
9403        if (!success)
9404            return false;
9405
9406        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9407
9408        // (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9409        uint32_t Rn = ReadCoreReg (n, &success);
9410        if (!success)
9411            return false;
9412
9413        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9414
9415        // R[d] = result;
9416        EmulateInstruction::Context context;
9417        context.type = eContextAddition;
9418        Register reg_n;
9419        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
9420        Register reg_m;
9421        reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9422
9423        context.SetRegisterRegisterOperands (reg_n, reg_m);
9424
9425        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9426            return false;
9427
9428        // if setflags then
9429            // APSR.N = result<31>;
9430            // APSR.Z = IsZeroBit(result);
9431            // APSR.C = carry;
9432            // APSR.V = overflow;
9433        if (setflags)
9434            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9435    }
9436    return true;
9437}
9438
9439// A8.6.213 SUB (register)
9440bool
9441EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9442{
9443#if 0
9444    if ConditionPassed() then
9445        EncodingSpecificOperations();
9446        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9447        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9448        if d == 15 then // Can only occur for ARM encoding
9449            ALUWritePC(result); // setflags is always FALSE here
9450        else
9451            R[d] = result;
9452            if setflags then
9453                APSR.N = result<31>;
9454                APSR.Z = IsZeroBit(result);
9455                APSR.C = carry;
9456                APSR.V = overflow;
9457#endif
9458
9459    bool success = false;
9460
9461    if (ConditionPassed(opcode))
9462    {
9463        uint32_t d;
9464        uint32_t n;
9465        uint32_t m;
9466        bool setflags;
9467        ARM_ShifterType shift_t;
9468        uint32_t shift_n;
9469
9470        switch (encoding)
9471        {
9472            case eEncodingT1:
9473                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9474                d = Bits32 (opcode, 2, 0);
9475                n = Bits32 (opcode, 5, 3);
9476                m = Bits32 (opcode, 8, 6);
9477                setflags = !InITBlock();
9478
9479                // (shift_t, shift_n) = (SRType_LSL, 0);
9480                shift_t = SRType_LSL;
9481                shift_n = 0;
9482
9483                break;
9484
9485            case eEncodingT2:
9486                // if Rd == ‘1111’ && S == ‘1’ then SEE CMP (register);
9487                // if Rn == ‘1101’ then SEE SUB (SP minus register);
9488                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9489                d = Bits32 (opcode, 11, 8);
9490                n = Bits32 (opcode, 19, 16);
9491                m = Bits32 (opcode, 3, 0);
9492                setflags = BitIsSet (opcode, 20);
9493
9494                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9495                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9496
9497                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9498                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9499                    return false;
9500
9501                break;
9502
9503            case eEncodingA1:
9504                // if Rn == ‘1101’ then SEE SUB (SP minus register);
9505                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9506                d = Bits32 (opcode, 15, 12);
9507                n = Bits32 (opcode, 19, 16);
9508                m = Bits32 (opcode, 3, 0);
9509                setflags = BitIsSet (opcode, 20);
9510
9511                // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9512                if ((d == 15) && setflags)
9513                    EmulateSUBSPcLrEtc (opcode, encoding);
9514
9515                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9516                shift_n = DecodeImmShiftARM (opcode, shift_t);
9517
9518                break;
9519
9520            default:
9521                return false;
9522        }
9523
9524        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9525        uint32_t Rm = ReadCoreReg (m, &success);
9526        if (!success)
9527            return false;
9528
9529        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9530
9531        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9532        uint32_t Rn = ReadCoreReg (n, &success);
9533        if (!success)
9534            return false;
9535
9536        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9537
9538        // if d == 15 then // Can only occur for ARM encoding
9539            // ALUWritePC(result); // setflags is always FALSE here
9540        // else
9541            // R[d] = result;
9542            // if setflags then
9543                // APSR.N = result<31>;
9544                // APSR.Z = IsZeroBit(result);
9545                // APSR.C = carry;
9546                // APSR.V = overflow;
9547
9548        EmulateInstruction::Context context;
9549        context.type = eContextSubtraction;
9550        Register reg_n;
9551        reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9552        Register reg_m;
9553        reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9554        context.SetRegisterRegisterOperands (reg_n, reg_m);
9555
9556        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9557            return false;
9558    }
9559    return true;
9560}
9561
9562// A8.6.202 STREX
9563// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9564// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9565bool
9566EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9567{
9568#if 0
9569    if ConditionPassed() then
9570        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9571        address = R[n] + imm32;
9572        if ExclusiveMonitorsPass(address,4) then
9573            MemA[address,4] = R[t];
9574            R[d] = 0;
9575        else
9576            R[d] = 1;
9577#endif
9578
9579    bool success = false;
9580
9581    if (ConditionPassed(opcode))
9582    {
9583        uint32_t d;
9584        uint32_t t;
9585        uint32_t n;
9586        uint32_t imm32;
9587        const uint32_t addr_byte_size = GetAddressByteSize();
9588
9589        switch (encoding)
9590        {
9591            case eEncodingT1:
9592                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9593                d = Bits32 (opcode, 11, 8);
9594                t = Bits32 (opcode, 15, 12);
9595                n = Bits32 (opcode, 19, 16);
9596                imm32 = Bits32 (opcode, 7, 0) << 2;
9597
9598                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9599                if (BadReg (d) || BadReg (t) || (n == 15))
9600                  return false;
9601
9602                // if d == n || d == t then UNPREDICTABLE;
9603                if ((d == n) || (d == t))
9604                  return false;
9605
9606                break;
9607
9608            case eEncodingA1:
9609                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9610                d = Bits32 (opcode, 15, 12);
9611                t = Bits32 (opcode, 3, 0);
9612                n = Bits32 (opcode, 19, 16);
9613                imm32 = 0;
9614
9615                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9616                if ((d == 15) || (t == 15) || (n == 15))
9617                    return false;
9618
9619                // if d == n || d == t then UNPREDICTABLE;
9620                if ((d == n) || (d == t))
9621                    return false;
9622
9623                break;
9624
9625            default:
9626                return false;
9627        }
9628
9629        // address = R[n] + imm32;
9630        uint32_t Rn = ReadCoreReg (n, &success);
9631        if (!success)
9632            return false;
9633
9634        addr_t address = Rn + imm32;
9635
9636        Register base_reg;
9637        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9638        Register data_reg;
9639        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9640        EmulateInstruction::Context context;
9641        context.type = eContextRegisterStore;
9642        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9643
9644        // if ExclusiveMonitorsPass(address,4) then
9645        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9646        //                                                         always return true.
9647        if (true)
9648        {
9649            // MemA[address,4] = R[t];
9650            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9651            if (!success)
9652                return false;
9653
9654            if (!MemAWrite (context, address, Rt, addr_byte_size))
9655                return false;
9656
9657            // R[d] = 0;
9658            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9659                return false;
9660        }
9661        else
9662        {
9663            // R[d] = 1;
9664            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9665                return false;
9666        }
9667    }
9668    return true;
9669}
9670
9671// A8.6.197 STRB (immediate, ARM)
9672bool
9673EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9674{
9675#if 0
9676    if ConditionPassed() then
9677        EncodingSpecificOperations();
9678        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9679        address = if index then offset_addr else R[n];
9680        MemU[address,1] = R[t]<7:0>;
9681        if wback then R[n] = offset_addr;
9682#endif
9683
9684    bool success = false;
9685
9686    if (ConditionPassed(opcode))
9687    {
9688        uint32_t t;
9689        uint32_t n;
9690        uint32_t imm32;
9691        bool index;
9692        bool add;
9693        bool wback;
9694
9695        switch (encoding)
9696        {
9697            case eEncodingA1:
9698                // if P == ‘0’ && W == ‘1’ then SEE STRBT;
9699                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9700                t = Bits32 (opcode, 15, 12);
9701                n = Bits32 (opcode, 19, 16);
9702                imm32 = Bits32 (opcode, 11, 0);
9703
9704                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9705                index = BitIsSet (opcode, 24);
9706                add = BitIsSet (opcode, 23);
9707                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9708
9709                // if t == 15 then UNPREDICTABLE;
9710                if (t == 15)
9711                    return false;
9712
9713                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9714                if (wback && ((n == 15) || (n == t)))
9715                    return false;
9716
9717                break;
9718
9719            default:
9720                return false;
9721        }
9722
9723        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9724        uint32_t Rn = ReadCoreReg (n, &success);
9725        if (!success)
9726            return false;
9727
9728        addr_t offset_addr;
9729        if (add)
9730            offset_addr = Rn + imm32;
9731        else
9732            offset_addr = Rn - imm32;
9733
9734        // address = if index then offset_addr else R[n];
9735        addr_t address;
9736        if (index)
9737            address = offset_addr;
9738        else
9739            address = Rn;
9740
9741        // MemU[address,1] = R[t]<7:0>;
9742        uint32_t Rt = ReadCoreReg (t, &success);
9743        if (!success)
9744            return false;
9745
9746        Register base_reg;
9747        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9748        Register data_reg;
9749        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9750        EmulateInstruction::Context context;
9751        context.type = eContextRegisterStore;
9752        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9753
9754        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9755            return false;
9756
9757        // if wback then R[n] = offset_addr;
9758        if (wback)
9759        {
9760            if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9761                return false;
9762        }
9763    }
9764    return true;
9765}
9766
9767// A8.6.194 STR (immediate, ARM)
9768bool
9769EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9770{
9771#if 0
9772    if ConditionPassed() then
9773        EncodingSpecificOperations();
9774        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9775        address = if index then offset_addr else R[n];
9776        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9777        if wback then R[n] = offset_addr;
9778#endif
9779
9780    bool success = false;
9781
9782    if (ConditionPassed(opcode))
9783    {
9784        uint32_t t;
9785        uint32_t n;
9786        uint32_t imm32;
9787        bool index;
9788        bool add;
9789        bool wback;
9790
9791        const uint32_t addr_byte_size = GetAddressByteSize();
9792
9793        switch (encoding)
9794        {
9795            case eEncodingA1:
9796                // if P == ‘0’ && W == ‘1’ then SEE STRT;
9797                // if Rn == ‘1101’ && P == ‘1’ && U == ‘0’ && W == ‘1’ && imm12 == ‘000000000100’ then SEE PUSH;
9798                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9799                t = Bits32 (opcode, 15, 12);
9800                n = Bits32 (opcode, 19, 16);
9801                imm32 = Bits32 (opcode, 11, 0);
9802
9803                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9804                index = BitIsSet (opcode, 24);
9805                add = BitIsSet (opcode, 23);
9806                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9807
9808                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9809                if (wback && ((n == 15) || (n == t)))
9810                    return false;
9811
9812                break;
9813
9814            default:
9815                return false;
9816        }
9817
9818        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9819        uint32_t Rn = ReadCoreReg (n, &success);
9820        if (!success)
9821            return false;
9822
9823        addr_t offset_addr;
9824        if (add)
9825            offset_addr = Rn + imm32;
9826        else
9827            offset_addr = Rn - imm32;
9828
9829        // address = if index then offset_addr else R[n];
9830        addr_t address;
9831        if (index)
9832            address = offset_addr;
9833        else
9834            address = Rn;
9835
9836        Register base_reg;
9837        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9838        Register data_reg;
9839        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9840        EmulateInstruction::Context context;
9841        context.type = eContextRegisterStore;
9842        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9843
9844        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9845        uint32_t Rt = ReadCoreReg (t, &success);
9846        if (!success)
9847            return false;
9848
9849        if (t == 15)
9850        {
9851            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
9852            if (!success)
9853                return false;
9854
9855            if (!MemUWrite (context, address, pc_value, addr_byte_size))
9856                return false;
9857        }
9858        else
9859        {
9860            if (!MemUWrite (context, address, Rt, addr_byte_size))
9861                  return false;
9862        }
9863
9864        // if wback then R[n] = offset_addr;
9865        if (wback)
9866        {
9867            context.type = eContextAdjustBaseRegister;
9868            context.SetImmediate (offset_addr);
9869
9870            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9871                return false;
9872        }
9873    }
9874    return true;
9875}
9876
9877// A8.6.66 LDRD (immediate)
9878// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
9879// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
9880bool
9881EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
9882{
9883#if 0
9884    if ConditionPassed() then
9885        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9886        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9887        address = if index then offset_addr else R[n];
9888        R[t] = MemA[address,4];
9889        R[t2] = MemA[address+4,4];
9890        if wback then R[n] = offset_addr;
9891#endif
9892
9893    bool success = false;
9894
9895    if (ConditionPassed(opcode))
9896    {
9897        uint32_t t;
9898        uint32_t t2;
9899        uint32_t n;
9900        uint32_t imm32;
9901        bool index;
9902        bool add;
9903        bool wback;
9904
9905        switch (encoding)
9906        {
9907            case eEncodingT1:
9908                //if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
9909                //if Rn == ‘1111’ then SEE LDRD (literal);
9910                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9911                t = Bits32 (opcode, 15, 12);
9912                t2 = Bits32 (opcode, 11, 8);
9913                n = Bits32 (opcode, 19, 16);
9914                imm32 = Bits32 (opcode, 7, 0) << 2;
9915
9916                //index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
9917                index = BitIsSet (opcode, 24);
9918                add = BitIsSet (opcode, 23);
9919                wback = BitIsSet (opcode, 21);
9920
9921                //if wback && (n == t || n == t2) then UNPREDICTABLE;
9922                if (wback && ((n == t) || (n == t2)))
9923                    return false;
9924
9925                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
9926                if (BadReg (t) || BadReg (t2) || (t == t2))
9927                    return false;
9928
9929                break;
9930
9931            case eEncodingA1:
9932                //if Rn == ‘1111’ then SEE LDRD (literal);
9933                //if Rt<0> == ‘1’ then UNPREDICTABLE;
9934                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
9935                t = Bits32 (opcode, 15, 12);
9936                if (BitIsSet (t, 0))
9937                    return false;
9938                t2 = t + 1;
9939                n = Bits32 (opcode, 19, 16);
9940                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
9941
9942                //index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9943                index = BitIsSet (opcode, 24);
9944                add = BitIsSet (opcode, 23);
9945                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9946
9947                //if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
9948                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
9949                    return false;
9950
9951                //if wback && (n == t || n == t2) then UNPREDICTABLE;
9952                if (wback && ((n == t) || (n == t2)))
9953                    return false;
9954
9955                //if t2 == 15 then UNPREDICTABLE;
9956                if (t2 == 15)
9957                    return false;
9958
9959                break;
9960
9961            default:
9962                return false;
9963        }
9964
9965        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9966        uint32_t Rn = ReadCoreReg (n, &success);
9967        if (!success)
9968            return false;
9969
9970        addr_t offset_addr;
9971        if (add)
9972                  offset_addr = Rn + imm32;
9973        else
9974            offset_addr = Rn - imm32;
9975
9976        //address = if index then offset_addr else R[n];
9977        addr_t address;
9978        if (index)
9979            address = offset_addr;
9980        else
9981            address = Rn;
9982
9983        //R[t] = MemA[address,4];
9984        Register base_reg;
9985        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9986
9987        EmulateInstruction::Context context;
9988        context.type = eContextRegisterLoad;
9989        context.SetRegisterPlusOffset (base_reg, address - Rn);
9990
9991        const uint32_t addr_byte_size = GetAddressByteSize();
9992        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
9993        if (!success)
9994            return false;
9995
9996        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
9997            return false;
9998
9999        //R[t2] = MemA[address+4,4];
10000
10001        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10002        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10003        if (!success)
10004            return false;
10005
10006        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10007            return false;
10008
10009        //if wback then R[n] = offset_addr;
10010        if (wback)
10011        {
10012            context.type = eContextAdjustBaseRegister;
10013            context.SetAddress (offset_addr);
10014
10015            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10016                return false;
10017        }
10018    }
10019    return true;
10020}
10021
10022// A8.6.68 LDRD (register)
10023// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10024// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10025bool
10026EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10027{
10028#if 0
10029    if ConditionPassed() then
10030        EncodingSpecificOperations();
10031        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10032        address = if index then offset_addr else R[n];
10033        R[t] = MemA[address,4];
10034        R[t2] = MemA[address+4,4];
10035        if wback then R[n] = offset_addr;
10036#endif
10037
10038    bool success = false;
10039
10040    if (ConditionPassed(opcode))
10041    {
10042        uint32_t t;
10043        uint32_t t2;
10044        uint32_t n;
10045        uint32_t m;
10046        bool index;
10047        bool add;
10048        bool wback;
10049
10050        switch (encoding)
10051        {
10052            case eEncodingA1:
10053                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10054                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10055                t = Bits32 (opcode, 15, 12);
10056                if (BitIsSet (t, 0))
10057                    return false;
10058                t2 = t + 1;
10059                n = Bits32 (opcode, 19, 16);
10060                m = Bits32 (opcode, 3, 0);
10061
10062                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10063                index = BitIsSet (opcode, 24);
10064                add = BitIsSet (opcode, 23);
10065                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10066
10067                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10068                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10069                  return false;
10070
10071                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10072                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10073                  return false;
10074
10075                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10076                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10077                  return false;
10078
10079                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10080                if ((ArchVersion() < 6) && wback && (m == n))
10081                  return false;
10082                break;
10083
10084            default:
10085                return false;
10086        }
10087
10088        uint32_t Rn = ReadCoreReg (n, &success);
10089        if (!success)
10090            return false;
10091        Register base_reg;
10092        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10093
10094        uint32_t Rm = ReadCoreReg (m, &success);
10095        if (!success)
10096            return false;
10097        Register offset_reg;
10098        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10099
10100        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10101        addr_t offset_addr;
10102        if (add)
10103            offset_addr = Rn + Rm;
10104        else
10105            offset_addr = Rn - Rm;
10106
10107        // address = if index then offset_addr else R[n];
10108        addr_t address;
10109        if (index)
10110            address = offset_addr;
10111        else
10112            address = Rn;
10113
10114        EmulateInstruction::Context context;
10115        context.type = eContextRegisterLoad;
10116        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10117
10118        // R[t] = MemA[address,4];
10119        const uint32_t addr_byte_size = GetAddressByteSize();
10120        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10121        if (!success)
10122            return false;
10123
10124        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10125            return false;
10126
10127        // R[t2] = MemA[address+4,4];
10128
10129        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10130        if (!success)
10131            return false;
10132
10133        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10134            return false;
10135
10136        // if wback then R[n] = offset_addr;
10137        if (wback)
10138        {
10139            context.type = eContextAdjustBaseRegister;
10140            context.SetAddress (offset_addr);
10141
10142            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10143                return false;
10144        }
10145    }
10146    return true;
10147}
10148
10149// A8.6.200 STRD (immediate)
10150// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10151// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10152bool
10153EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10154{
10155#if 0
10156    if ConditionPassed() then
10157        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10158        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10159        address = if index then offset_addr else R[n];
10160        MemA[address,4] = R[t];
10161        MemA[address+4,4] = R[t2];
10162        if wback then R[n] = offset_addr;
10163#endif
10164
10165    bool success = false;
10166
10167    if (ConditionPassed(opcode))
10168    {
10169        uint32_t t;
10170        uint32_t t2;
10171        uint32_t n;
10172        uint32_t imm32;
10173        bool index;
10174        bool add;
10175        bool wback;
10176
10177        switch (encoding)
10178        {
10179            case eEncodingT1:
10180                // if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10181                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10182                t = Bits32 (opcode, 15, 12);
10183                t2 = Bits32 (opcode, 11, 8);
10184                n = Bits32 (opcode, 19, 16);
10185                imm32 = Bits32 (opcode, 7, 0) << 2;
10186
10187                // index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
10188                index = BitIsSet (opcode, 24);
10189                add = BitIsSet (opcode, 23);
10190                wback = BitIsSet (opcode, 21);
10191
10192                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10193                if (wback && ((n == t) || (n == t2)))
10194                    return false;
10195
10196                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10197                if ((n == 15) || BadReg (t) || BadReg (t2))
10198                    return false;
10199
10200                break;
10201
10202            case eEncodingA1:
10203                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10204                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10205                t = Bits32 (opcode, 15, 12);
10206                if (BitIsSet (t, 0))
10207                    return false;
10208
10209                t2 = t + 1;
10210                n = Bits32 (opcode, 19, 16);
10211                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10212
10213                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10214                index = BitIsSet (opcode, 24);
10215                add = BitIsSet (opcode, 23);
10216                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10217
10218                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10219                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10220                    return false;
10221
10222                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10223                if (wback && ((n == 15) || (n == t) || (n == t2)))
10224                    return false;
10225
10226                // if t2 == 15 then UNPREDICTABLE;
10227                if (t2 == 15)
10228                    return false;
10229
10230                break;
10231
10232            default:
10233                return false;
10234        }
10235
10236        Register base_reg;
10237        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10238
10239        uint32_t Rn = ReadCoreReg (n, &success);
10240        if (!success)
10241            return false;
10242
10243        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10244        addr_t offset_addr;
10245        if (add)
10246            offset_addr = Rn + imm32;
10247        else
10248            offset_addr = Rn - imm32;
10249
10250        //address = if index then offset_addr else R[n];
10251        addr_t address;
10252        if (index)
10253            address = offset_addr;
10254        else
10255            address = Rn;
10256
10257        //MemA[address,4] = R[t];
10258        Register data_reg;
10259        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10260
10261        uint32_t data = ReadCoreReg (t, &success);
10262        if (!success)
10263            return false;
10264
10265        EmulateInstruction::Context context;
10266        context.type = eContextRegisterStore;
10267        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10268
10269        const uint32_t addr_byte_size = GetAddressByteSize();
10270
10271        if (!MemAWrite (context, address, data, addr_byte_size))
10272            return false;
10273
10274        //MemA[address+4,4] = R[t2];
10275        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t2);
10276        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10277
10278        data = ReadCoreReg (t2, &success);
10279        if (!success)
10280            return false;
10281
10282        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10283            return false;
10284
10285        //if wback then R[n] = offset_addr;
10286        if (wback)
10287        {
10288            context.type = eContextAdjustBaseRegister;
10289            context.SetAddress (offset_addr);
10290
10291            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10292                return false;
10293        }
10294    }
10295    return true;
10296}
10297
10298
10299// A8.6.201 STRD (register)
10300bool
10301EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10302{
10303#if 0
10304    if ConditionPassed() then
10305        EncodingSpecificOperations();
10306        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10307        address = if index then offset_addr else R[n];
10308        MemA[address,4] = R[t];
10309        MemA[address+4,4] = R[t2];
10310        if wback then R[n] = offset_addr;
10311#endif
10312
10313    bool success = false;
10314
10315    if (ConditionPassed(opcode))
10316    {
10317        uint32_t t;
10318        uint32_t t2;
10319        uint32_t n;
10320        uint32_t m;
10321        bool index;
10322        bool add;
10323        bool wback;
10324
10325        switch (encoding)
10326        {
10327            case eEncodingA1:
10328                // if Rt<0> == ‘1’ then UNPREDICTABLE;
10329                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10330                t = Bits32 (opcode, 15, 12);
10331                if (BitIsSet (t, 0))
10332                   return false;
10333
10334                t2 = t+1;
10335                n = Bits32 (opcode, 19, 16);
10336                m = Bits32 (opcode, 3, 0);
10337
10338                // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10339                index = BitIsSet (opcode, 24);
10340                add = BitIsSet (opcode, 23);
10341                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10342
10343                // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10344                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10345                   return false;
10346
10347                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10348                if ((t2 == 15) || (m == 15))
10349                   return false;
10350
10351                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10352                if (wback && ((n == 15) || (n == t) || (n == t2)))
10353                   return false;
10354
10355                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10356                if ((ArchVersion() < 6) && wback && (m == n))
10357                   return false;
10358
10359                break;
10360
10361            default:
10362                return false;
10363        }
10364
10365        Register base_reg;
10366        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10367        Register offset_reg;
10368        offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10369        Register data_reg;
10370        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10371
10372        uint32_t Rn = ReadCoreReg (n, &success);
10373        if (!success)
10374            return false;
10375
10376        uint32_t Rm = ReadCoreReg (m, &success);
10377        if (!success)
10378            return false;
10379
10380        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10381        addr_t offset_addr;
10382        if (add)
10383            offset_addr = Rn + Rm;
10384        else
10385            offset_addr = Rn - Rm;
10386
10387        // address = if index then offset_addr else R[n];
10388        addr_t address;
10389        if (index)
10390            address = offset_addr;
10391        else
10392            address = Rn;
10393                          // MemA[address,4] = R[t];
10394        uint32_t Rt = ReadCoreReg (t, &success);
10395        if (!success)
10396            return false;
10397
10398        EmulateInstruction::Context context;
10399        context.type = eContextRegisterStore;
10400        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10401
10402        const uint32_t addr_byte_size = GetAddressByteSize();
10403
10404        if (!MemAWrite (context, address, Rt, addr_byte_size))
10405            return false;
10406
10407        // MemA[address+4,4] = R[t2];
10408        uint32_t Rt2 = ReadCoreReg (t2, &success);
10409        if (!success)
10410            return false;
10411
10412        data_reg.num = dwarf_r0 + t2;
10413
10414        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10415
10416        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10417            return false;
10418
10419        // if wback then R[n] = offset_addr;
10420        if (wback)
10421        {
10422            context.type = eContextAdjustBaseRegister;
10423            context.SetAddress (offset_addr);
10424
10425            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10426                return false;
10427
10428        }
10429    }
10430    return true;
10431}
10432
10433// A8.6.319 VLDM
10434// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10435// an ARM core register.
10436bool
10437EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10438{
10439#if 0
10440    if ConditionPassed() then
10441        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10442        address = if add then R[n] else R[n]-imm32;
10443        if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10444        for r = 0 to regs-1
10445            if single_regs then
10446                S[d+r] = MemA[address,4]; address = address+4;
10447            else
10448                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10449                // Combine the word-aligned words in the correct order for current endianness.
10450                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10451#endif
10452
10453    bool success = false;
10454
10455    if (ConditionPassed(opcode))
10456    {
10457        bool single_regs;
10458        bool add;
10459        bool wback;
10460        uint32_t d;
10461        uint32_t n;
10462        uint32_t imm32;
10463        uint32_t regs;
10464
10465        switch (encoding)
10466        {
10467            case eEncodingT1:
10468            case eEncodingA1:
10469                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10470                // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10471                // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10472                // if P == U && W == ‘1’ then UNDEFINED;
10473                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10474                    return false;
10475
10476                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10477                // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10478                single_regs = false;
10479                add = BitIsSet (opcode, 23);
10480                wback = BitIsSet (opcode, 21);
10481
10482                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10483                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10484                n = Bits32 (opcode, 19, 16);
10485                imm32 = Bits32 (opcode, 7, 0) << 2;
10486
10487                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FLDMX”.
10488                regs = Bits32 (opcode, 7, 0) / 2;
10489
10490                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10491                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10492                    return false;
10493
10494                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10495                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10496                    return false;
10497
10498                break;
10499
10500            case eEncodingT2:
10501            case eEncodingA2:
10502                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10503                // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10504                // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10505                // if P == U && W == ‘1’ then UNDEFINED;
10506                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10507                    return false;
10508
10509                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10510                // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10511                single_regs = true;
10512                add = BitIsSet (opcode, 23);
10513                wback = BitIsSet (opcode, 21);
10514                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10515                n = Bits32 (opcode, 19, 16);
10516
10517                // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10518                imm32 = Bits32 (opcode, 7, 0) << 2;
10519                regs = Bits32 (opcode, 7, 0);
10520
10521                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10522                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10523                    return false;
10524
10525                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10526                if ((regs == 0) || ((d + regs) > 32))
10527                    return false;
10528                break;
10529
10530            default:
10531                return false;
10532        }
10533
10534        Register base_reg;
10535        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10536
10537        uint32_t Rn = ReadCoreReg (n, &success);
10538        if (!success)
10539            return false;
10540
10541        // address = if add then R[n] else R[n]-imm32;
10542        addr_t address;
10543        if (add)
10544            address = Rn;
10545        else
10546            address = Rn - imm32;
10547
10548        // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10549        EmulateInstruction::Context context;
10550
10551        if (wback)
10552        {
10553            uint32_t value;
10554            if (add)
10555                value = Rn + imm32;
10556            else
10557                value = Rn - imm32;
10558
10559            context.type = eContextAdjustBaseRegister;
10560            context.SetImmediateSigned (value - Rn);
10561            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10562                return false;
10563
10564        }
10565
10566        const uint32_t addr_byte_size = GetAddressByteSize();
10567        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10568
10569        context.type = eContextRegisterLoad;
10570
10571        // for r = 0 to regs-1
10572        for (uint32_t r = 0; r < regs; ++r)
10573        {
10574            if (single_regs)
10575            {
10576                // S[d+r] = MemA[address,4]; address = address+4;
10577                context.SetRegisterPlusOffset (base_reg, address - Rn);
10578
10579                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10580                if (!success)
10581                    return false;
10582
10583                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10584                    return false;
10585
10586                address = address + 4;
10587            }
10588            else
10589            {
10590                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10591                context.SetRegisterPlusOffset (base_reg, address - Rn);
10592                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10593                if (!success)
10594                    return false;
10595
10596                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10597                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10598                if (!success)
10599                    return false;
10600
10601                address = address + 8;
10602                // // Combine the word-aligned words in the correct order for current endianness.
10603                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10604                uint64_t data;
10605                if (m_byte_order == eByteOrderBig)
10606                {
10607                    data = word1;
10608                    data = (data << 32) | word2;
10609                }
10610                else
10611                {
10612                    data = word2;
10613                    data = (data << 32) | word1;
10614                }
10615
10616                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10617                    return false;
10618            }
10619        }
10620    }
10621    return true;
10622}
10623
10624// A8.6.399 VSTM
10625// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10626// ARM core register.
10627bool
10628EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10629{
10630#if 0
10631    if ConditionPassed() then
10632        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10633        address = if add then R[n] else R[n]-imm32;
10634        if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10635        for r = 0 to regs-1
10636            if single_regs then
10637                MemA[address,4] = S[d+r]; address = address+4;
10638            else
10639                // Store as two word-aligned words in the correct order for current endianness.
10640                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10641                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10642                address = address+8;
10643#endif
10644
10645    bool success = false;
10646
10647    if (ConditionPassed (opcode))
10648    {
10649        bool single_regs;
10650        bool add;
10651        bool wback;
10652        uint32_t d;
10653        uint32_t n;
10654        uint32_t imm32;
10655        uint32_t regs;
10656
10657        switch (encoding)
10658        {
10659            case eEncodingT1:
10660            case eEncodingA1:
10661                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10662                // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10663                // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10664                // if P == U && W == ‘1’ then UNDEFINED;
10665                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10666                    return false;
10667
10668                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10669                // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10670                single_regs = false;
10671                add = BitIsSet (opcode, 23);
10672                wback = BitIsSet (opcode, 21);
10673
10674                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10675                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10676                n = Bits32 (opcode, 19, 16);
10677                imm32 = Bits32 (opcode, 7, 0) << 2;
10678
10679                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FSTMX”.
10680                regs = Bits32 (opcode, 7, 0) / 2;
10681
10682                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10683                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10684                    return false;
10685
10686                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10687                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10688                    return false;
10689
10690                break;
10691
10692            case eEncodingT2:
10693            case eEncodingA2:
10694                // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10695                // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10696                // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10697                // if P == U && W == ‘1’ then UNDEFINED;
10698                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10699                    return false;
10700
10701                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10702                // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10703                single_regs = true;
10704                add = BitIsSet (opcode, 23);
10705                wback = BitIsSet (opcode, 21);
10706                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10707                n = Bits32 (opcode, 19, 16);
10708
10709                // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10710                imm32 = Bits32 (opcode, 7, 0) << 2;
10711                regs = Bits32 (opcode, 7, 0);
10712
10713                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10714                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10715                    return false;
10716
10717                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10718                if ((regs == 0) || ((d + regs) > 32))
10719                    return false;
10720
10721                break;
10722
10723            default:
10724                return false;
10725        }
10726
10727        Register base_reg;
10728        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10729
10730        uint32_t Rn = ReadCoreReg (n, &success);
10731        if (!success)
10732            return false;
10733
10734        // address = if add then R[n] else R[n]-imm32;
10735        addr_t address;
10736        if (add)
10737            address = Rn;
10738        else
10739            address = Rn - imm32;
10740
10741        EmulateInstruction::Context context;
10742        // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10743        if (wback)
10744        {
10745            uint32_t value;
10746            if (add)
10747                value = Rn + imm32;
10748            else
10749                value = Rn - imm32;
10750
10751            context.type = eContextAdjustBaseRegister;
10752            context.SetRegisterPlusOffset (base_reg, value - Rn);
10753
10754            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10755                return false;
10756        }
10757
10758        const uint32_t addr_byte_size = GetAddressByteSize();
10759        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10760
10761        context.type = eContextRegisterStore;
10762        // for r = 0 to regs-1
10763        for (int r = 0; r < regs; ++r)
10764        {
10765            Register data_reg;
10766            data_reg.SetRegister (eRegisterKindDWARF, 0);
10767            if (single_regs)
10768            {
10769                // MemA[address,4] = S[d+r]; address = address+4;
10770                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10771                if (!success)
10772                    return false;
10773
10774                data_reg.num = start_reg + d + r;
10775                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10776                if (!MemAWrite (context, address, data, addr_byte_size))
10777                    return false;
10778
10779                address = address + 4;
10780            }
10781            else
10782            {
10783                // // Store as two word-aligned words in the correct order for current endianness.
10784                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10785                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10786                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10787                if (!success)
10788                    return false;
10789
10790                data_reg.num = start_reg + d + r;
10791
10792                if (m_byte_order == eByteOrderBig)
10793                {
10794                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10795                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10796                        return false;
10797
10798                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10799                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10800                        return false;
10801                }
10802                else
10803                {
10804                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10805                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10806                        return false;
10807
10808                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10809                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10810                        return false;
10811                }
10812                // address = address+8;
10813                address = address + 8;
10814            }
10815        }
10816    }
10817    return true;
10818}
10819
10820// A8.6.320
10821// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10822// an optional offset.
10823bool
10824EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10825{
10826#if 0
10827    if ConditionPassed() then
10828        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10829        base = if n == 15 then Align(PC,4) else R[n];
10830        address = if add then (base + imm32) else (base - imm32);
10831        if single_reg then
10832            S[d] = MemA[address,4];
10833        else
10834            word1 = MemA[address,4]; word2 = MemA[address+4,4];
10835            // Combine the word-aligned words in the correct order for current endianness.
10836            D[d] = if BigEndian() then word1:word2 else word2:word1;
10837#endif
10838
10839    bool success = false;
10840
10841    if (ConditionPassed (opcode))
10842    {
10843        bool single_reg;
10844        bool add;
10845        uint32_t imm32;
10846        uint32_t d;
10847        uint32_t n;
10848
10849        switch (encoding)
10850        {
10851            case eEncodingT1:
10852            case eEncodingA1:
10853                // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10854                single_reg = false;
10855                add = BitIsSet (opcode, 23);
10856                imm32 = Bits32 (opcode, 7, 0) << 2;
10857
10858                // d = UInt(D:Vd); n = UInt(Rn);
10859                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10860                n = Bits32 (opcode, 19, 16);
10861
10862                break;
10863
10864            case eEncodingT2:
10865            case eEncodingA2:
10866                // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10867                single_reg = true;
10868                add = BitIsSet (opcode, 23);
10869                imm32 = Bits32 (opcode, 7, 0) << 2;
10870
10871                // d = UInt(Vd:D); n = UInt(Rn);
10872                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10873                n = Bits32 (opcode, 19, 16);
10874
10875                break;
10876
10877            default:
10878                return false;
10879        }
10880        Register base_reg;
10881        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10882
10883        uint32_t Rn = ReadCoreReg (n, &success);
10884        if (!success)
10885            return false;
10886
10887        // base = if n == 15 then Align(PC,4) else R[n];
10888        uint32_t base;
10889        if (n == 15)
10890            base = AlignPC (Rn);
10891        else
10892            base = Rn;
10893
10894        // address = if add then (base + imm32) else (base - imm32);
10895        addr_t address;
10896        if (add)
10897            address = base + imm32;
10898        else
10899            address = base - imm32;
10900
10901        const uint32_t addr_byte_size = GetAddressByteSize();
10902        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
10903
10904        EmulateInstruction::Context context;
10905        context.type = eContextRegisterLoad;
10906        context.SetRegisterPlusOffset (base_reg, address - base);
10907
10908        if (single_reg)
10909        {
10910            // S[d] = MemA[address,4];
10911            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10912            if (!success)
10913                return false;
10914
10915            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
10916                return false;
10917        }
10918        else
10919        {
10920            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
10921            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10922            if (!success)
10923                return false;
10924
10925            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
10926            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10927            if (!success)
10928                return false;
10929            // // Combine the word-aligned words in the correct order for current endianness.
10930            // D[d] = if BigEndian() then word1:word2 else word2:word1;
10931            uint64_t data64;
10932            if (m_byte_order == eByteOrderBig)
10933            {
10934                data64 = word1;
10935                data64 = (data64 << 32) | word2;
10936            }
10937            else
10938            {
10939                data64 = word2;
10940                data64 = (data64 << 32) | word1;
10941            }
10942
10943            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
10944                return false;
10945        }
10946    }
10947    return true;
10948}
10949
10950// A8.6.400 VSTR
10951// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
10952// optional offset.
10953bool
10954EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
10955{
10956#if 0
10957    if ConditionPassed() then
10958        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10959        address = if add then (R[n] + imm32) else (R[n] - imm32);
10960        if single_reg then
10961            MemA[address,4] = S[d];
10962        else
10963            // Store as two word-aligned words in the correct order for current endianness.
10964            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
10965            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
10966#endif
10967
10968    bool success = false;
10969
10970    if (ConditionPassed (opcode))
10971    {
10972        bool single_reg;
10973        bool add;
10974        uint32_t imm32;
10975        uint32_t d;
10976        uint32_t n;
10977
10978        switch (encoding)
10979        {
10980            case eEncodingT1:
10981            case eEncodingA1:
10982                // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10983                single_reg = false;
10984                add = BitIsSet (opcode, 23);
10985                imm32 = Bits32 (opcode, 7, 0) << 2;
10986
10987                // d = UInt(D:Vd); n = UInt(Rn);
10988                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10989                n = Bits32 (opcode, 19, 16);
10990
10991                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
10992                if ((n == 15) && (CurrentInstrSet() != eModeARM))
10993                    return false;
10994
10995                break;
10996
10997            case eEncodingT2:
10998            case eEncodingA2:
10999                // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
11000                single_reg = true;
11001                add = BitIsSet (opcode, 23);
11002                imm32 = Bits32 (opcode, 7, 0) << 2;
11003
11004                // d = UInt(Vd:D); n = UInt(Rn);
11005                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11006                n = Bits32 (opcode, 19, 16);
11007
11008                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11009                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11010                    return false;
11011
11012                break;
11013
11014            default:
11015                return false;
11016        }
11017
11018        Register base_reg;
11019        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11020
11021        uint32_t Rn = ReadCoreReg (n, &success);
11022        if (!success)
11023            return false;
11024
11025        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11026        addr_t address;
11027        if (add)
11028            address = Rn + imm32;
11029        else
11030            address = Rn - imm32;
11031
11032        const uint32_t addr_byte_size = GetAddressByteSize();
11033        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11034
11035        Register data_reg;
11036        data_reg.SetRegister (eRegisterKindDWARF, start_reg + d);
11037        EmulateInstruction::Context context;
11038        context.type = eContextRegisterStore;
11039        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11040
11041        if (single_reg)
11042        {
11043            // MemA[address,4] = S[d];
11044            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11045            if (!success)
11046                return false;
11047
11048            if (!MemAWrite (context, address, data, addr_byte_size))
11049                return false;
11050        }
11051        else
11052        {
11053            // // Store as two word-aligned words in the correct order for current endianness.
11054            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11055            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11056            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11057            if (!success)
11058                return false;
11059
11060            if (m_byte_order == eByteOrderBig)
11061            {
11062                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11063                    return false;
11064
11065                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11066                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11067                    return false;
11068            }
11069            else
11070            {
11071                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11072                    return false;
11073
11074                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11075                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11076                    return false;
11077            }
11078        }
11079    }
11080    return true;
11081}
11082
11083// A8.6.307 VLDI1 (multiple single elements)
11084// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11085// element of each register is loaded.
11086bool
11087EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11088{
11089#if 0
11090    if ConditionPassed() then
11091        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11092        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11093        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11094        for r = 0 to regs-1
11095            for e = 0 to elements-1
11096                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11097                address = address + ebytes;
11098#endif
11099
11100    bool success = false;
11101
11102    if (ConditionPassed (opcode))
11103    {
11104        uint32_t regs;
11105        uint32_t alignment;
11106        uint32_t ebytes;
11107        uint32_t esize;
11108        uint32_t elements;
11109        uint32_t d;
11110        uint32_t n;
11111        uint32_t m;
11112        bool wback;
11113        bool register_index;
11114
11115        switch (encoding)
11116        {
11117            case eEncodingT1:
11118            case eEncodingA1:
11119            {
11120                // case type of
11121                    // when ‘0111’
11122                        // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11123                    // when ‘1010’
11124                        // regs = 2; if align == ‘11’ then UNDEFINED;
11125                    // when ‘0110’
11126                        // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11127                    // when ‘0010’
11128                        // regs = 4;
11129                    // otherwise
11130                        // SEE “Related encodings”;
11131                uint32_t type = Bits32 (opcode, 11, 8);
11132                uint32_t align = Bits32 (opcode, 5, 4);
11133                if (type == 7) // '0111'
11134                {
11135                    regs = 1;
11136                    if (BitIsSet (align, 1))
11137                        return false;
11138                }
11139                else if (type == 10) // '1010'
11140                {
11141                    regs = 2;
11142                    if (align == 3)
11143                        return false;
11144
11145                }
11146                else if (type == 6) // '0110'
11147                {
11148                    regs = 3;
11149                    if (BitIsSet (align, 1))
11150                        return false;
11151                }
11152                else if (type == 2) // '0010'
11153                {
11154                    regs = 4;
11155                }
11156                else
11157                    return false;
11158
11159                // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11160                if (align == 0)
11161                    alignment = 1;
11162                else
11163                    alignment = 4 << align;
11164
11165                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11166                ebytes = 1 << Bits32 (opcode, 7, 6);
11167                esize = 8 * ebytes;
11168                elements = 8 / ebytes;
11169
11170                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11171                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11172                n = Bits32 (opcode, 19, 15);
11173                m = Bits32 (opcode, 3, 0);
11174
11175                // wback = (m != 15); register_index = (m != 15 && m != 13);
11176                wback = (m != 15);
11177                register_index = ((m != 15) && (m != 13));
11178
11179                // if d+regs > 32 then UNPREDICTABLE;
11180                if ((d + regs) > 32)
11181                    return false;
11182            }
11183                break;
11184
11185            default:
11186                return false;
11187        }
11188
11189        Register base_reg;
11190        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11191
11192        uint32_t Rn = ReadCoreReg (n, &success);
11193        if (!success)
11194            return false;
11195
11196        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11197        addr_t address = Rn;
11198        if ((address % alignment) != 0)
11199            return false;
11200
11201        EmulateInstruction::Context context;
11202        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11203        if (wback)
11204        {
11205            uint32_t Rm = ReadCoreReg (m, &success);
11206            if (!success)
11207                return false;
11208
11209            uint32_t offset;
11210            if (register_index)
11211                offset = Rm;
11212            else
11213                offset = 8 * regs;
11214
11215            uint32_t value = Rn + offset;
11216            context.type = eContextAdjustBaseRegister;
11217            context.SetRegisterPlusOffset (base_reg, offset);
11218
11219            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11220                return false;
11221
11222        }
11223
11224        // for r = 0 to regs-1
11225        for (int r = 0; r < regs; ++r)
11226        {
11227            // for e = 0 to elements-1
11228            uint64_t assembled_data = 0;
11229            for (int e = 0; e < elements; ++e)
11230            {
11231                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11232                context.type = eContextRegisterLoad;
11233                context.SetRegisterPlusOffset (base_reg, address - Rn);
11234                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11235                if (!success)
11236                    return false;
11237
11238                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11239
11240                // address = address + ebytes;
11241                address = address + ebytes;
11242            }
11243            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11244                return false;
11245        }
11246    }
11247    return true;
11248}
11249
11250// A8.6.308 VLD1 (single element to one lane)
11251//
11252bool
11253EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11254{
11255#if 0
11256    if ConditionPassed() then
11257        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11258        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11259        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11260        Elem[D[d],index,esize] = MemU[address,ebytes];
11261#endif
11262
11263    bool success = false;
11264
11265    if (ConditionPassed (opcode))
11266    {
11267        uint32_t ebytes;
11268        uint32_t esize;
11269        uint32_t index;
11270        uint32_t alignment;
11271        uint32_t d;
11272        uint32_t n;
11273        uint32_t m;
11274        bool wback;
11275        bool register_index;
11276
11277        switch (encoding)
11278        {
11279            case eEncodingT1:
11280            case eEncodingA1:
11281            {
11282                uint32_t size = Bits32 (opcode, 11, 10);
11283                uint32_t index_align = Bits32 (opcode, 7, 4);
11284                // if size == ‘11’ then SEE VLD1 (single element to all lanes);
11285                if (size == 3)
11286                   return EmulateVLD1SingleAll (opcode, encoding);
11287                // case size of
11288                if (size == 0) // when '00'
11289                {
11290                    // if index_align<0> != ‘0’ then UNDEFINED;
11291                    if (BitIsClear (index_align, 0))
11292                        return false;
11293
11294                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11295                    ebytes = 1;
11296                    esize = 8;
11297                    index = Bits32 (index_align, 3, 1);
11298                    alignment = 1;
11299                }
11300                else if (size == 1) // when ‘01’
11301                {
11302                    // if index_align<1> != ‘0’ then UNDEFINED;
11303                    if (BitIsClear (index_align, 1))
11304                        return false;
11305
11306                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11307                    ebytes = 2;
11308                    esize = 16;
11309                    index = Bits32 (index_align, 3, 2);
11310
11311                    // alignment = if index_align<0> == ‘0’ then 1 else 2;
11312                    if (BitIsClear (index_align, 0))
11313                        alignment = 1;
11314                    else
11315                        alignment = 2;
11316                }
11317                else if (size == 2) // when ‘10’
11318                {
11319                    // if index_align<2> != ‘0’ then UNDEFINED;
11320                    if (BitIsClear (index_align, 2))
11321                        return false;
11322
11323                    // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11324                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11325                        return false;
11326
11327                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11328                    ebytes = 4;
11329                    esize = 32;
11330                    index = Bit32 (index_align, 3);
11331
11332                    // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11333                    if (Bits32 (index_align, 1, 0) == 0)
11334                        alignment = 1;
11335                    else
11336                        alignment = 4;
11337                }
11338                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11339                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11340                n = Bits32 (opcode, 19, 16);
11341                m = Bits32 (opcode, 3, 0);
11342
11343                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11344                wback = (m != 15);
11345                register_index = ((m != 15) && (m != 13));
11346
11347                if (n == 15)
11348                    return false;
11349
11350            }
11351                break;
11352
11353            default:
11354                return false;
11355        }
11356
11357        Register base_reg;
11358        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11359
11360        uint32_t Rn = ReadCoreReg (n, &success);
11361        if (!success)
11362            return false;
11363
11364        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11365        addr_t address = Rn;
11366        if ((address % alignment) != 0)
11367            return false;
11368
11369        EmulateInstruction::Context context;
11370        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11371        if (wback)
11372        {
11373            uint32_t Rm = ReadCoreReg (m, &success);
11374            if (!success)
11375                return false;
11376
11377            uint32_t offset;
11378            if (register_index)
11379                offset = Rm;
11380            else
11381                offset = ebytes;
11382
11383            uint32_t value = Rn + offset;
11384
11385            context.type = eContextAdjustBaseRegister;
11386            context.SetRegisterPlusOffset (base_reg, offset);
11387
11388            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11389                return false;
11390        }
11391
11392        // Elem[D[d],index,esize] = MemU[address,ebytes];
11393        uint32_t element = MemURead (context, address, esize, 0, &success);
11394        if (!success)
11395            return false;
11396
11397        element = element << (index * esize);
11398
11399        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11400        if (!success)
11401            return false;
11402
11403        uint64_t all_ones = -1;
11404        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11405                                                          // at element & to the right of element.
11406        if (index > 0)
11407            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11408                                                                     // now mask should be 0's where element goes & 1's
11409                                                                     // everywhere else.
11410
11411        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11412        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11413
11414        context.type = eContextRegisterLoad;
11415        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11416            return false;
11417    }
11418    return true;
11419}
11420
11421// A8.6.391 VST1 (multiple single elements)
11422// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11423// interleaving.  Every element of each register is stored.
11424bool
11425EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11426{
11427#if 0
11428    if ConditionPassed() then
11429        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11430        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11431        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11432        for r = 0 to regs-1
11433            for e = 0 to elements-1
11434                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11435                address = address + ebytes;
11436#endif
11437
11438    bool success = false;
11439
11440    if (ConditionPassed (opcode))
11441    {
11442        uint32_t regs;
11443        uint32_t alignment;
11444        uint32_t ebytes;
11445        uint32_t esize;
11446        uint32_t elements;
11447        uint32_t d;
11448        uint32_t n;
11449        uint32_t m;
11450        bool wback;
11451        bool register_index;
11452
11453        switch (encoding)
11454        {
11455            case eEncodingT1:
11456            case eEncodingA1:
11457            {
11458                uint32_t type = Bits32 (opcode, 11, 8);
11459                uint32_t align = Bits32 (opcode, 5, 4);
11460
11461                // case type of
11462                if (type == 7)    // when ‘0111’
11463                {
11464                    // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11465                    regs = 1;
11466                    if (BitIsSet (align, 1))
11467                        return false;
11468                }
11469                else if (type == 10) // when ‘1010’
11470                {
11471                    // regs = 2; if align == ‘11’ then UNDEFINED;
11472                    regs = 2;
11473                    if (align == 3)
11474                        return false;
11475                }
11476                else if (type == 6) // when ‘0110’
11477                {
11478                    // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11479                    regs = 3;
11480                    if (BitIsSet (align, 1))
11481                        return false;
11482                }
11483                else if (type == 2) // when ‘0010’
11484                    // regs = 4;
11485                    regs = 4;
11486                else // otherwise
11487                    // SEE “Related encodings”;
11488                    return false;
11489
11490                // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11491                if (align == 0)
11492                    alignment = 0;
11493                else
11494                    alignment = 4 << align;
11495
11496                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11497                ebytes = 1 << Bits32 (opcode,7, 6);
11498                esize = 8 * ebytes;
11499                elements = 8 / ebytes;
11500
11501                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11502                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11503                n = Bits32 (opcode, 19, 16);
11504                m = Bits32 (opcode, 3, 0);
11505
11506                // wback = (m != 15); register_index = (m != 15 && m != 13);
11507                wback = (m != 15);
11508                register_index = ((m != 15) && (m != 13));
11509
11510                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11511                if ((d + regs) > 32)
11512                    return false;
11513
11514                if (n == 15)
11515                    return false;
11516
11517            }
11518                break;
11519
11520            default:
11521                return false;
11522        }
11523
11524        Register base_reg;
11525        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11526
11527        uint32_t Rn = ReadCoreReg (n, &success);
11528        if (!success)
11529            return false;
11530
11531        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11532        addr_t address = Rn;
11533        if ((address % alignment) != 0)
11534            return false;
11535
11536        EmulateInstruction::Context context;
11537        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11538        if (wback)
11539        {
11540            uint32_t Rm = ReadCoreReg (m, &success);
11541            if (!success)
11542                return false;
11543
11544            uint32_t offset;
11545            if (register_index)
11546                offset = Rm;
11547            else
11548                offset = 8 * regs;
11549
11550            context.type = eContextAdjustBaseRegister;
11551            context.SetRegisterPlusOffset (base_reg, offset);
11552
11553            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11554                return false;
11555        }
11556
11557        context.type = eContextRegisterStore;
11558        Register data_reg;
11559        data_reg.SetRegister (eRegisterKindDWARF, 0);
11560        // for r = 0 to regs-1
11561        for (int r = 0; r < regs; ++r)
11562        {
11563            data_reg.num = dwarf_d0 + d + r;
11564            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11565            if (!success)
11566                return false;
11567
11568             // for e = 0 to elements-1
11569            for (int e = 0; e < elements; ++e)
11570            {
11571                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11572                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11573
11574                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11575                if (!MemUWrite (context, address, word, ebytes))
11576                    return false;
11577
11578                // address = address + ebytes;
11579                address = address + ebytes;
11580            }
11581        }
11582    }
11583    return true;
11584}
11585
11586// A8.6.392 VST1 (single element from one lane)
11587// This instruction stores one element to memory from one element of a register.
11588bool
11589EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11590{
11591#if 0
11592    if ConditionPassed() then
11593        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11594        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11595        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11596        MemU[address,ebytes] = Elem[D[d],index,esize];
11597#endif
11598
11599    bool success = false;
11600
11601    if (ConditionPassed (opcode))
11602    {
11603        uint32_t ebytes;
11604        uint32_t esize;
11605        uint32_t index;
11606        uint32_t alignment;
11607        uint32_t d;
11608        uint32_t n;
11609        uint32_t m;
11610        bool wback;
11611        bool register_index;
11612
11613        switch (encoding)
11614        {
11615            case eEncodingT1:
11616            case eEncodingA1:
11617            {
11618                uint32_t size = Bits32 (opcode, 11, 10);
11619                uint32_t index_align = Bits32 (opcode, 7, 4);
11620
11621                // if size == ‘11’ then UNDEFINED;
11622                if (size == 3)
11623                    return false;
11624
11625                // case size of
11626                if (size == 0) // when ‘00’
11627                {
11628                    // if index_align<0> != ‘0’ then UNDEFINED;
11629                    if (BitIsClear (index_align, 0))
11630                        return false;
11631                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11632                    ebytes = 1;
11633                    esize = 8;
11634                    index = Bits32 (index_align, 3, 1);
11635                    alignment = 1;
11636                }
11637                else if (size == 1) // when ‘01’
11638                {
11639                    // if index_align<1> != ‘0’ then UNDEFINED;
11640                    if (BitIsClear (index_align, 1))
11641                        return false;
11642
11643                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11644                    ebytes = 2;
11645                    esize = 16;
11646                    index = Bits32 (index_align, 3, 2);
11647
11648                    // alignment = if index_align<0> == ‘0’ then 1 else 2;
11649                    if (BitIsClear (index_align, 0))
11650                        alignment = 1;
11651                    else
11652                        alignment = 2;
11653                }
11654                else if (size == 2) // when ‘10’
11655                {
11656                    // if index_align<2> != ‘0’ then UNDEFINED;
11657                    if (BitIsClear (index_align, 2))
11658                        return false;
11659
11660                    // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11661                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11662                        return false;
11663
11664                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11665                    ebytes = 4;
11666                    esize = 32;
11667                    index = Bit32 (index_align, 3);
11668
11669                    // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11670                    if (Bits32 (index_align, 1, 0) == 0)
11671                        alignment = 1;
11672                    else
11673                        alignment = 4;
11674                }
11675                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11676                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11677                n = Bits32 (opcode, 19, 16);
11678                m = Bits32 (opcode, 3, 0);
11679
11680                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11681                wback = (m != 15);
11682                register_index = ((m != 15) && (m != 13));
11683
11684                if (n == 15)
11685                    return false;
11686            }
11687                break;
11688
11689            default:
11690                return false;
11691        }
11692
11693        Register base_reg;
11694        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11695
11696        uint32_t Rn = ReadCoreReg (n, &success);
11697        if (!success)
11698            return false;
11699
11700        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11701        addr_t address = Rn;
11702        if ((address % alignment) != 0)
11703            return false;
11704
11705        EmulateInstruction::Context context;
11706        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11707        if (wback)
11708        {
11709            uint32_t Rm = ReadCoreReg (m, &success);
11710            if (!success)
11711                return false;
11712
11713            uint32_t offset;
11714            if (register_index)
11715                offset = Rm;
11716            else
11717                offset = ebytes;
11718
11719            context.type = eContextAdjustBaseRegister;
11720            context.SetRegisterPlusOffset (base_reg, offset);
11721
11722            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11723                return false;
11724        }
11725
11726        // MemU[address,ebytes] = Elem[D[d],index,esize];
11727        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11728        if (!success)
11729            return false;
11730
11731        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11732
11733        Register data_reg;
11734        data_reg.SetRegister (eRegisterKindDWARF, dwarf_d0 + d);
11735        context.type = eContextRegisterStore;
11736        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11737
11738        if (!MemUWrite (context, address, word, ebytes))
11739            return false;
11740    }
11741    return true;
11742}
11743
11744// A8.6.309 VLD1 (single element to all lanes)
11745// This instruction loads one element from memory into every element of one or two vectors.
11746bool
11747EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11748{
11749#if 0
11750    if ConditionPassed() then
11751        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11752        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11753        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11754        replicated_element = Replicate(MemU[address,ebytes], elements);
11755        for r = 0 to regs-1
11756            D[d+r] = replicated_element;
11757#endif
11758
11759    bool success = false;
11760
11761    if (ConditionPassed (opcode))
11762    {
11763        uint32_t ebytes;
11764        uint32_t elements;
11765        uint32_t regs;
11766        uint32_t alignment;
11767        uint32_t d;
11768        uint32_t n;
11769        uint32_t m;
11770        bool wback;
11771        bool register_index;
11772
11773        switch (encoding)
11774        {
11775            case eEncodingT1:
11776            case eEncodingA1:
11777            {
11778                //if size == ‘11’ || (size == ‘00’ && a == ‘1’) then UNDEFINED;
11779                uint32_t size = Bits32 (opcode, 7, 6);
11780                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11781                    return false;
11782
11783                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == ‘0’ then 1 else 2;
11784                ebytes = 1 << size;
11785                elements = 8 / ebytes;
11786                if (BitIsClear (opcode, 5))
11787                    regs = 1;
11788                else
11789                    regs = 2;
11790
11791                //alignment = if a == ‘0’ then 1 else ebytes;
11792                if (BitIsClear (opcode, 4))
11793                    alignment = 1;
11794                else
11795                    alignment = ebytes;
11796
11797                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11798                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11799                n = Bits32 (opcode, 19, 16);
11800                m = Bits32 (opcode, 3, 0);
11801
11802                //wback = (m != 15); register_index = (m != 15 && m != 13);
11803                wback = (m != 15);
11804                register_index = ((m != 15) && (m != 13));
11805
11806                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11807                if ((d + regs) > 32)
11808                    return false;
11809
11810                if (n == 15)
11811                    return false;
11812            }
11813                break;
11814
11815            default:
11816                break;
11817        }
11818
11819        Register base_reg;
11820        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
11821
11822        uint32_t Rn = ReadCoreReg (n, &success);
11823        if (!success)
11824            return false;
11825
11826        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11827        addr_t address = Rn;
11828        if ((address % alignment) != 0)
11829            return false;
11830
11831        EmulateInstruction::Context context;
11832        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11833        if (wback)
11834        {
11835            uint32_t Rm = ReadCoreReg (m, &success);
11836            if (!success)
11837                return false;
11838
11839            uint32_t offset;
11840            if (register_index)
11841                offset = Rm;
11842            else
11843                offset = ebytes;
11844
11845            context.type = eContextAdjustBaseRegister;
11846            context.SetRegisterPlusOffset (base_reg, offset);
11847
11848            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11849                return false;
11850        }
11851
11852        // replicated_element = Replicate(MemU[address,ebytes], elements);
11853
11854        context.type = eContextRegisterLoad;
11855        uint64_t word = MemURead (context, address, ebytes, 0, &success);
11856        if (!success)
11857            return false;
11858
11859        uint64_t replicated_element;
11860        uint32_t esize = ebytes * 8;
11861        for (int e = 0; e < elements; ++e)
11862            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
11863
11864        // for r = 0 to regs-1
11865        for (int r = 0; r < regs; ++r)
11866        {
11867            // D[d+r] = replicated_element;
11868            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
11869                return false;
11870        }
11871    }
11872    return true;
11873}
11874
11875// B6.2.13 SUBS PC, LR and related instructions
11876//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
11877// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
11878bool
11879EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
11880{
11881#if 0
11882    if ConditionPassed() then
11883        EncodingSpecificOperations();
11884        if CurrentInstrSet() == InstrSet_ThumbEE then
11885            UNPREDICTABLE;
11886        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
11887        case opcode of
11888            when ‘0000’ result = R[n] AND operand2; // AND
11889            when ‘0001result = R[n] EOR operand2; // EOR
11890            when ‘0010’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB
11891            when ‘0011’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB
11892            when ‘0100’ (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD
11893            when ‘0101’ (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
11894            when ‘0110’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
11895            when ‘0111’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
11896            when1100result = R[n] OR operand2; // ORR
11897            when1101result = operand2; // MOV
11898            when1110result = R[n] AND NOT(operand2); // BIC
11899            when1111result = NOT(operand2); // MVN
11900        CPSRWriteByInstr(SPSR[], ‘1111’, TRUE);
11901        BranchWritePC(result);
11902#endif
11903
11904    bool success = false;
11905
11906    if (ConditionPassed (opcode))
11907    {
11908        uint32_t n;
11909        uint32_t m;
11910        uint32_t imm32;
11911        bool register_form;
11912        ARM_ShifterType shift_t;
11913        uint32_t shift_n;
11914        uint32_t code;
11915
11916        switch (encoding)
11917        {
11918            case eEncodingT1:
11919                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
11920                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = ‘0010’; // = SUB
11921                n = 14;
11922                imm32 = Bits32 (opcode, 7, 0);
11923                register_form = false;
11924                code = 2;
11925
11926                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
11927                if (InITBlock() && !LastInITBlock())
11928                    return false;
11929
11930                break;
11931
11932            case eEncodingA1:
11933                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
11934                n = Bits32 (opcode, 19, 16);
11935                imm32 = ARMExpandImm (opcode);
11936                register_form = false;
11937                code = Bits32 (opcode, 24, 21);
11938
11939                break;
11940
11941            case eEncodingA2:
11942                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
11943                n = Bits32 (opcode, 19, 16);
11944                m = Bits32 (opcode, 3, 0);
11945                register_form = true;
11946
11947                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
11948                shift_n = DecodeImmShiftARM (opcode, shift_t);
11949
11950                break;
11951
11952            default:
11953                return false;
11954        }
11955
11956        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
11957        uint32_t operand2;
11958        if (register_form)
11959        {
11960            uint32_t Rm = ReadCoreReg (m, &success);
11961            if (!success)
11962                return false;
11963
11964            operand2 = Shift (Rm, shift_t, shift_n, APSR_C);
11965
11966        }
11967        else
11968        {
11969            operand2 = imm32;
11970        }
11971
11972        uint32_t Rn = ReadCoreReg (n, &success);
11973        if (!success)
11974            return false;
11975
11976        AddWithCarryResult result;
11977
11978        // case opcode of
11979        switch (code)
11980        {
11981            case 0: // when ‘0000’
11982                // result = R[n] AND operand2; // AND
11983                result.result = Rn & operand2;
11984                break;
11985
11986            case 1: // when ‘0001’
11987                // result = R[n] EOR operand2; // EOR
11988                result.result = Rn ^ operand2;
11989                break;
11990
11991            case 2: // when ‘0010’
11992                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB
11993                result = AddWithCarry (Rn, ~(operand2), 1);
11994                break;
11995
11996            case 3: // when ‘0011’
11997                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB
11998                result = AddWithCarry (~(Rn), operand2, 1);
11999                break;
12000
12001            case 4: // when ‘0100’
12002                // (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD
12003                result = AddWithCarry (Rn, operand2, 0);
12004                break;
12005
12006            case 5: // when ‘0101’
12007                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12008                result = AddWithCarry (Rn, operand2, APSR_C);
12009                break;
12010
12011            case 6: // when ‘0110’
12012                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12013                result = AddWithCarry (Rn, ~(operand2), APSR_C);
12014                break;
12015
12016            case 7: // when ‘0111’
12017                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12018                result = AddWithCarry (~(Rn), operand2, APSR_C);
12019                break;
12020
12021            case 10: // when ‘1100’
12022                // result = R[n] OR operand2; // ORR
12023                result.result = Rn | operand2;
12024                break;
12025
12026            case 11: // when ‘1101’
12027                // result = operand2; // MOV
12028                result.result = operand2;
12029                break;
12030
12031            case 12: // when ‘1110’
12032                // result = R[n] AND NOT(operand2); // BIC
12033                result.result = Rn & ~(operand2);
12034                break;
12035
12036            case 15: // when ‘1111’
12037                // result = NOT(operand2); // MVN
12038                result.result = ~(operand2);
12039                break;
12040
12041            default:
12042                return false;
12043        }
12044        // CPSRWriteByInstr(SPSR[], ‘1111’, TRUE);
12045
12046        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12047        // the best.
12048        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12049        if (!success)
12050            return false;
12051
12052        CPSRWriteByInstr (spsr, 15, true);
12053
12054        // BranchWritePC(result);
12055        EmulateInstruction::Context context;
12056        context.type = eContextAdjustPC;
12057        context.SetImmediate (result.result);
12058
12059        BranchWritePC (context, result.result);
12060    }
12061    return true;
12062}
12063
12064EmulateInstructionARM::ARMOpcode*
12065EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
12066{
12067    static ARMOpcode
12068    g_arm_opcodes[] =
12069    {
12070        //----------------------------------------------------------------------
12071        // Prologue instructions
12072        //----------------------------------------------------------------------
12073
12074        // push register(s)
12075        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12076        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12077
12078        // set r7 to point to a stack offset
12079        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12080        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12081        // copy the stack pointer to ip
12082        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12083        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12084        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12085
12086        // adjust the stack pointer
12087        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12088        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12089
12090        // push one register
12091        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12092        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12093
12094        // vector push consecutive extension register(s)
12095        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12096        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12097
12098        //----------------------------------------------------------------------
12099        // Epilogue instructions
12100        //----------------------------------------------------------------------
12101
12102        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12103        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12104        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12105        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12106
12107        //----------------------------------------------------------------------
12108        // Supervisor Call (previously Software Interrupt)
12109        //----------------------------------------------------------------------
12110        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12111
12112        //----------------------------------------------------------------------
12113        // Branch instructions
12114        //----------------------------------------------------------------------
12115        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12116        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12117        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12118        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12119        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12120        // for example, "bx lr"
12121        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12122        // bxj
12123        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12124
12125        //----------------------------------------------------------------------
12126        // Data-processing instructions
12127        //----------------------------------------------------------------------
12128        // adc (immediate)
12129        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12130        // adc (register)
12131        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12132        // add (immediate)
12133        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12134        // add (register)
12135        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12136        // add (register-shifted register)
12137        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12138        // adr
12139        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12140        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12141        // and (immediate)
12142        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12143        // and (register)
12144        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12145        // bic (immediate)
12146        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12147        // bic (register)
12148        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12149        // eor (immediate)
12150        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12151        // eor (register)
12152        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12153        // orr (immediate)
12154        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12155        // orr (register)
12156        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12157        // rsb (immediate)
12158        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12159        // rsb (register)
12160        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12161        // rsc (immediate)
12162        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12163        // rsc (register)
12164        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12165        // sbc (immediate)
12166        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12167        // sbc (register)
12168        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12169        // sub (immediate, ARM)
12170        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12171        // sub (sp minus immediate)
12172        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12173        // sub (register)
12174        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12175        // teq (immediate)
12176        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12177        // teq (register)
12178        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12179        // tst (immediate)
12180        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12181        // tst (register)
12182        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12183
12184        // mov (immediate)
12185        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12186        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12187        // mov (register)
12188        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12189        // mvn (immediate)
12190        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12191        // mvn (register)
12192        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12193        // cmn (immediate)
12194        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12195        // cmn (register)
12196        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12197        // cmp (immediate)
12198        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12199        // cmp (register)
12200        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12201        // asr (immediate)
12202        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12203        // asr (register)
12204        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12205        // lsl (immediate)
12206        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12207        // lsl (register)
12208        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12209        // lsr (immediate)
12210        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12211        // lsr (register)
12212        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12213        // rrx is a special case encoding of ror (immediate)
12214        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12215        // ror (immediate)
12216        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12217        // ror (register)
12218        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12219        // mul
12220        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12221        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12222        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12223
12224        //----------------------------------------------------------------------
12225        // Load instructions
12226        //----------------------------------------------------------------------
12227        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12228        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12229        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12230        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12231        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12232        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12233        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12234        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12235        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12236        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12237        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12238        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12239        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12240        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12241        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12242        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12243        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12244        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12245        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12246        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12247        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12248        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12249        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12250        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12251        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12252
12253        //----------------------------------------------------------------------
12254        // Store instructions
12255        //----------------------------------------------------------------------
12256        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12257        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12258        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12259        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12260        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12261        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12262        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12263        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12264        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12265        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12266        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12267        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12268        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12269        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12270        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12271        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12272        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12273
12274        //----------------------------------------------------------------------
12275        // Other instructions
12276        //----------------------------------------------------------------------
12277        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12278        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12279        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12280        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12281        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12282
12283    };
12284    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12285
12286    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12287    {
12288        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
12289            return &g_arm_opcodes[i];
12290    }
12291    return NULL;
12292}
12293
12294
12295EmulateInstructionARM::ARMOpcode*
12296EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
12297{
12298
12299    static ARMOpcode
12300    g_thumb_opcodes[] =
12301    {
12302        //----------------------------------------------------------------------
12303        // Prologue instructions
12304        //----------------------------------------------------------------------
12305
12306        // push register(s)
12307        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12308        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12309        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12310
12311        // set r7 to point to a stack offset
12312        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12313        // copy the stack pointer to r7
12314        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12315        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12316        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12317
12318        // PC-relative load into register (see also EmulateADDSPRm)
12319        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12320
12321        // adjust the stack pointer
12322        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12323        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12324        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12325        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12326        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12327
12328        // vector push consecutive extension register(s)
12329        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12330        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12331
12332        //----------------------------------------------------------------------
12333        // Epilogue instructions
12334        //----------------------------------------------------------------------
12335
12336        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12337        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12338        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12339        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12340        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12341        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12342        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12343
12344        //----------------------------------------------------------------------
12345        // Supervisor Call (previously Software Interrupt)
12346        //----------------------------------------------------------------------
12347        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12348
12349        //----------------------------------------------------------------------
12350        // If Then makes up to four following instructions conditional.
12351        //----------------------------------------------------------------------
12352        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12353
12354        //----------------------------------------------------------------------
12355        // Branch instructions
12356        //----------------------------------------------------------------------
12357        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12358        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12359        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12360        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12361        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12362        // J1 == J2 == 1
12363        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12364        // J1 == J2 == 1
12365        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12366        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12367        // for example, "bx lr"
12368        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12369        // bxj
12370        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12371        // compare and branch
12372        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12373        // table branch byte
12374        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12375        // table branch halfword
12376        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12377
12378        //----------------------------------------------------------------------
12379        // Data-processing instructions
12380        //----------------------------------------------------------------------
12381        // adc (immediate)
12382        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12383        // adc (register)
12384        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12385        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12386        // add (register)
12387        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12388        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12389        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12390        // adr
12391        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12392        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12393        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12394        // and (immediate)
12395        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12396        // and (register)
12397        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12398        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12399        // bic (immediate)
12400        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12401        // bic (register)
12402        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12403        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12404        // eor (immediate)
12405        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12406        // eor (register)
12407        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12408        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12409        // orr (immediate)
12410        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12411        // orr (register)
12412        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12413        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12414        // rsb (immediate)
12415        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12416        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12417        // rsb (register)
12418        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12419        // sbc (immediate)
12420        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12421        // sbc (register)
12422        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12423        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12424        // add (immediate, Thumb)
12425        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12426        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12427        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12428        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12429        // sub (immediate, Thumb)
12430        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12431        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12432        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12433        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12434        // sub (sp minus immediate)
12435        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12436        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12437        // sub (register)
12438        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12439        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12440        // teq (immediate)
12441        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12442        // teq (register)
12443        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12444        // tst (immediate)
12445        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12446        // tst (register)
12447        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12448        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12449
12450
12451        // move from high register to high register
12452        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12453        // move from low register to low register
12454        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12455        // mov{s}<c>.w <Rd>, <Rm>
12456        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12457        // move immediate
12458        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12459        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12460        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12461        // mvn (immediate)
12462        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12463        // mvn (register)
12464        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12465        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12466        // cmn (immediate)
12467        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12468        // cmn (register)
12469        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12470        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12471        // cmp (immediate)
12472        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12473        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12474        // cmp (register) (Rn and Rm both from r0-r7)
12475        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12476        // cmp (register) (Rn and Rm not both from r0-r7)
12477        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12478        // asr (immediate)
12479        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12480        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12481        // asr (register)
12482        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12483        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12484        // lsl (immediate)
12485        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12486        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12487        // lsl (register)
12488        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12489        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12490        // lsr (immediate)
12491        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12492        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12493        // lsr (register)
12494        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12495        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12496        // rrx is a special case encoding of ror (immediate)
12497        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12498        // ror (immediate)
12499        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12500        // ror (register)
12501        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12502        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12503        // mul
12504        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12505        // mul
12506        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12507        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12508
12509
12510        //----------------------------------------------------------------------
12511        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12512        // otherwise the wrong instructions will be selected.
12513        //----------------------------------------------------------------------
12514
12515        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12516        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12517
12518        //----------------------------------------------------------------------
12519        // Load instructions
12520        //----------------------------------------------------------------------
12521        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12522        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12523        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12524        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12525        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12526        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12527        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12528                  // Thumb2 PC-relative load into register
12529        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12530        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12531        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12532        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12533        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12534        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12535        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12536        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12537        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12538        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12539        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12540        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12541        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12542        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12543        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12544        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12545        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12546        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12547        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12548        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12549        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12550        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12551        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12552        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12553        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12554        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12555        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12556        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12557        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12558        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12559        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12560        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12561        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12562
12563        //----------------------------------------------------------------------
12564        // Store instructions
12565        //----------------------------------------------------------------------
12566        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12567        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12568        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12569        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12570        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12571        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12572        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12573        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12574        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12575        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12576        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12577        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12578        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12579        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12580        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12581        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12582        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12583        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12584        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12585        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12586        { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12587        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12588
12589        //----------------------------------------------------------------------
12590        // Other instructions
12591        //----------------------------------------------------------------------
12592        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12593        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12594        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12595        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12596        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12597        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12598        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12599        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12600    };
12601
12602    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12603    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12604    {
12605        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
12606            return &g_thumb_opcodes[i];
12607    }
12608    return NULL;
12609}
12610
12611bool
12612EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12613{
12614    m_arch = arch;
12615    m_arm_isa = 0;
12616    const char *arch_cstr = arch.GetArchitectureName ();
12617    if (arch_cstr)
12618    {
12619        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12620        else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
12621        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12622        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12623        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12624        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12625        else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
12626        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12627        else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
12628        else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
12629    }
12630    return m_arm_isa != 0;
12631}
12632
12633bool
12634EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr)
12635{
12636    m_opcode = insn_opcode;
12637
12638    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12639        m_opcode_mode = eModeThumb;
12640	else
12641	{
12642		AddressClass addr_class = inst_addr.GetAddressClass();
12643
12644    	if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12645        	m_opcode_mode = eModeARM;
12646    	else if (addr_class == eAddressClassCodeAlternateISA)
12647        	m_opcode_mode = eModeThumb;
12648    	else
12649        	return false;
12650	}
12651    return true;
12652}
12653
12654bool
12655EmulateInstructionARM::ReadInstruction ()
12656{
12657    bool success = false;
12658    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12659    if (success)
12660    {
12661        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12662        if (success)
12663        {
12664            Context read_inst_context;
12665            read_inst_context.type = eContextReadOpcode;
12666            read_inst_context.SetNoArgs ();
12667
12668            if (m_opcode_cpsr & MASK_CPSR_T)
12669            {
12670                m_opcode_mode = eModeThumb;
12671                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12672
12673                if (success)
12674                {
12675                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12676                    {
12677                        m_opcode.SetOpcode16 (thumb_opcode);
12678                    }
12679                    else
12680                    {
12681                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12682                    }
12683                }
12684            }
12685            else
12686            {
12687                m_opcode_mode = eModeARM;
12688                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12689            }
12690        }
12691    }
12692    if (!success)
12693    {
12694        m_opcode_mode = eModeInvalid;
12695        m_opcode_pc = LLDB_INVALID_ADDRESS;
12696    }
12697    return success;
12698}
12699
12700uint32_t
12701EmulateInstructionARM::ArchVersion ()
12702{
12703    return m_arm_isa;
12704}
12705
12706bool
12707EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
12708{
12709
12710    const uint32_t cond = CurrentCond (opcode);
12711
12712    if (cond == UINT32_MAX)
12713        return false;
12714
12715    bool result = false;
12716    switch (UnsignedBits(cond, 3, 1))
12717    {
12718    case 0:
12719		if (m_opcode_cpsr == 0)
12720			return true;
12721		result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12722		break;
12723    case 1:
12724 		if (m_opcode_cpsr == 0)
12725			return true;
12726		result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12727		break;
12728    case 2:
12729 		if (m_opcode_cpsr == 0)
12730			return true;
12731		result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12732		break;
12733    case 3:
12734 		if (m_opcode_cpsr == 0)
12735			return true;
12736		result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12737		break;
12738    case 4:
12739 		if (m_opcode_cpsr == 0)
12740			return true;
12741		result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12742		break;
12743    case 5:
12744  		if (m_opcode_cpsr == 0)
12745			return true;
12746       	else
12747		{
12748            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12749            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12750            result = n == v;
12751        }
12752        break;
12753    case 6:
12754  		if (m_opcode_cpsr == 0)
12755			return true;
12756       	else
12757		{
12758            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12759            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12760            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12761        }
12762        break;
12763    case 7:
12764        result = true;
12765        break;
12766    }
12767
12768    if (cond & 1)
12769        result = !result;
12770    return result;
12771}
12772
12773uint32_t
12774EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12775{
12776    switch (m_opcode_mode)
12777    {
12778    default:
12779    case eModeInvalid:
12780        break;
12781
12782    case eModeARM:
12783        return UnsignedBits(opcode, 31, 28);
12784
12785    case eModeThumb:
12786        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12787        // 'cond' field of the encoding.
12788        {
12789            const uint32_t byte_size = m_opcode.GetByteSize();
12790            if (byte_size == 2)
12791            {
12792                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
12793                    return Bits32(opcode, 11, 7);
12794            }
12795            else
12796            {
12797                assert (byte_size == 4);
12798                if (Bits32(opcode, 31, 27) == 0x1e &&
12799                    Bits32(opcode, 15, 14) == 0x02 &&
12800                    Bits32(opcode, 12, 12) == 0x00 &&
12801                    Bits32(opcode, 25, 22) <= 0x0d)
12802                {
12803                    return Bits32(opcode, 25, 22);
12804                }
12805            }
12806
12807            return m_it_session.GetCond();
12808        }
12809    }
12810    return UINT32_MAX;  // Return invalid value
12811}
12812
12813bool
12814EmulateInstructionARM::InITBlock()
12815{
12816    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
12817}
12818
12819bool
12820EmulateInstructionARM::LastInITBlock()
12821{
12822    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
12823}
12824
12825bool
12826EmulateInstructionARM::BadMode (uint32_t mode)
12827{
12828
12829    switch (mode)
12830    {
12831        case 16: return false; // '10000'
12832        case 17: return false; // '10001'
12833        case 18: return false; // '10010'
12834        case 19: return false; // '10011'
12835        case 22: return false; // '10110'
12836        case 23: return false; // '10111'
12837        case 27: return false; // '11011'
12838        case 31: return false; // '11111'
12839        default: return true;
12840    }
12841    return true;
12842}
12843
12844bool
12845EmulateInstructionARM::CurrentModeIsPrivileged ()
12846{
12847    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
12848
12849    if (BadMode (mode))
12850        return false;
12851
12852    if (mode == 16)
12853                  return false;
12854
12855    return true;
12856}
12857
12858void
12859EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
12860{
12861    bool privileged = CurrentModeIsPrivileged();
12862
12863    uint32_t tmp_cpsr = 0;
12864
12865    tmp_cpsr = tmp_cpsr | (Bits32 (m_opcode_cpsr, 23, 20) << 20);
12866
12867    if (BitIsSet (bytemask, 3))
12868    {
12869        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
12870        if (affect_execstate)
12871            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
12872    }
12873
12874    if (BitIsSet (bytemask, 2))
12875    {
12876        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
12877    }
12878
12879    if (BitIsSet (bytemask, 1))
12880    {
12881        if (affect_execstate)
12882            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
12883        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
12884        if (privileged)
12885            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
12886    }
12887
12888    if (BitIsSet (bytemask, 0))
12889    {
12890        if (privileged)
12891            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
12892        if (affect_execstate)
12893            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
12894        if (privileged)
12895            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
12896    }
12897
12898    m_opcode_cpsr = tmp_cpsr;
12899}
12900
12901
12902bool
12903EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
12904{
12905    addr_t target;
12906
12907    // Check the current instruction set.
12908    if (CurrentInstrSet() == eModeARM)
12909        target = addr & 0xfffffffc;
12910    else
12911        target = addr & 0xfffffffe;
12912
12913    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12914        return false;
12915
12916    return true;
12917}
12918
12919// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
12920bool
12921EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
12922{
12923    addr_t target;
12924    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
12925    // we want to record it and issue a WriteRegister callback so the clients
12926    // can track the mode changes accordingly.
12927    bool cpsr_changed = false;
12928
12929    if (BitIsSet(addr, 0))
12930    {
12931        if (CurrentInstrSet() != eModeThumb)
12932        {
12933            SelectInstrSet(eModeThumb);
12934            cpsr_changed = true;
12935        }
12936        target = addr & 0xfffffffe;
12937        context.SetMode (eModeThumb);
12938    }
12939    else if (BitIsClear(addr, 1))
12940    {
12941        if (CurrentInstrSet() != eModeARM)
12942        {
12943            SelectInstrSet(eModeARM);
12944            cpsr_changed = true;
12945        }
12946        target = addr & 0xfffffffc;
12947        context.SetMode (eModeARM);
12948    }
12949    else
12950        return false; // address<1:0> == '10' => UNPREDICTABLE
12951
12952    if (cpsr_changed)
12953    {
12954        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
12955            return false;
12956    }
12957    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12958        return false;
12959
12960    return true;
12961}
12962
12963// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
12964bool
12965EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
12966{
12967    if (ArchVersion() >= ARMv5T)
12968        return BXWritePC(context, addr);
12969    else
12970        return BranchWritePC((const Context)context, addr);
12971}
12972
12973// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
12974bool
12975EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
12976{
12977    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
12978        return BXWritePC(context, addr);
12979    else
12980        return BranchWritePC((const Context)context, addr);
12981}
12982
12983EmulateInstructionARM::Mode
12984EmulateInstructionARM::CurrentInstrSet ()
12985{
12986    return m_opcode_mode;
12987}
12988
12989// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
12990// ReadInstruction() is performed.  This function has a side effect of updating
12991// the m_new_inst_cpsr member variable if necessary.
12992bool
12993EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
12994{
12995    m_new_inst_cpsr = m_opcode_cpsr;
12996    switch (arm_or_thumb)
12997    {
12998    default:
12999        return false;
13000    eModeARM:
13001        // Clear the T bit.
13002        m_new_inst_cpsr &= ~MASK_CPSR_T;
13003        break;
13004    eModeThumb:
13005        // Set the T bit.
13006        m_new_inst_cpsr |= MASK_CPSR_T;
13007        break;
13008    }
13009    return true;
13010}
13011
13012// This function returns TRUE if the processor currently provides support for
13013// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13014// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13015bool
13016EmulateInstructionARM::UnalignedSupport()
13017{
13018    return (ArchVersion() >= ARMv7);
13019}
13020
13021// The main addition and subtraction instructions can produce status information
13022// about both unsigned carry and signed overflow conditions.  This status
13023// information can be used to synthesize multi-word additions and subtractions.
13024EmulateInstructionARM::AddWithCarryResult
13025EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13026{
13027    uint32_t result;
13028    uint8_t carry_out;
13029    uint8_t overflow;
13030
13031    uint64_t unsigned_sum = x + y + carry_in;
13032    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13033
13034    result = UnsignedBits(unsigned_sum, 31, 0);
13035//    carry_out = (result == unsigned_sum ? 0 : 1);
13036    overflow = ((int32_t)result == signed_sum ? 0 : 1);
13037
13038    if (carry_in)
13039        carry_out = ((int32_t) x >= (int32_t) y) ? 1 : 0;
13040    else
13041        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13042
13043    AddWithCarryResult res = { result, carry_out, overflow };
13044    return res;
13045}
13046
13047uint32_t
13048EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13049{
13050    uint32_t reg_kind, reg_num;
13051    switch (num)
13052    {
13053    case SP_REG:
13054        reg_kind = eRegisterKindGeneric;
13055        reg_num  = LLDB_REGNUM_GENERIC_SP;
13056        break;
13057    case LR_REG:
13058        reg_kind = eRegisterKindGeneric;
13059        reg_num  = LLDB_REGNUM_GENERIC_RA;
13060        break;
13061    case PC_REG:
13062        reg_kind = eRegisterKindGeneric;
13063        reg_num  = LLDB_REGNUM_GENERIC_PC;
13064        break;
13065    default:
13066        if (num < SP_REG)
13067        {
13068            reg_kind = eRegisterKindDWARF;
13069            reg_num  = dwarf_r0 + num;
13070        }
13071        else
13072        {
13073            assert(0 && "Invalid register number");
13074            *success = false;
13075            return UINT32_MAX;
13076        }
13077        break;
13078    }
13079
13080    // Read our register.
13081    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13082
13083    // When executing an ARM instruction , PC reads as the address of the current
13084    // instruction plus 8.
13085    // When executing a Thumb instruction , PC reads as the address of the current
13086    // instruction plus 4.
13087    if (num == 15)
13088    {
13089        if (CurrentInstrSet() == eModeARM)
13090            val += 8;
13091        else
13092            val += 4;
13093    }
13094
13095    return val;
13096}
13097
13098// Write the result to the ARM core register Rd, and optionally update the
13099// condition flags based on the result.
13100//
13101// This helper method tries to encapsulate the following pseudocode from the
13102// ARM Architecture Reference Manual:
13103//
13104// if d == 15 then         // Can only occur for encoding A1
13105//     ALUWritePC(result); // setflags is always FALSE here
13106// else
13107//     R[d] = result;
13108//     if setflags then
13109//         APSR.N = result<31>;
13110//         APSR.Z = IsZeroBit(result);
13111//         APSR.C = carry;
13112//         // APSR.V unchanged
13113//
13114// In the above case, the API client does not pass in the overflow arg, which
13115// defaults to ~0u.
13116bool
13117EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13118                                                  const uint32_t result,
13119                                                  const uint32_t Rd,
13120                                                  bool setflags,
13121                                                  const uint32_t carry,
13122                                                  const uint32_t overflow)
13123{
13124    if (Rd == 15)
13125    {
13126        if (!ALUWritePC (context, result))
13127            return false;
13128    }
13129    else
13130    {
13131        uint32_t reg_kind, reg_num;
13132        switch (Rd)
13133        {
13134        case SP_REG:
13135            reg_kind = eRegisterKindGeneric;
13136            reg_num  = LLDB_REGNUM_GENERIC_SP;
13137            break;
13138        case LR_REG:
13139            reg_kind = eRegisterKindGeneric;
13140            reg_num  = LLDB_REGNUM_GENERIC_RA;
13141            break;
13142        default:
13143            reg_kind = eRegisterKindDWARF;
13144            reg_num  = dwarf_r0 + Rd;
13145        }
13146        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13147            return false;
13148        if (setflags)
13149            return WriteFlags (context, result, carry, overflow);
13150    }
13151    return true;
13152}
13153
13154// This helper method tries to encapsulate the following pseudocode from the
13155// ARM Architecture Reference Manual:
13156//
13157// APSR.N = result<31>;
13158// APSR.Z = IsZeroBit(result);
13159// APSR.C = carry;
13160// APSR.V = overflow
13161//
13162// Default arguments can be specified for carry and overflow parameters, which means
13163// not to update the respective flags.
13164bool
13165EmulateInstructionARM::WriteFlags (Context &context,
13166                                   const uint32_t result,
13167                                   const uint32_t carry,
13168                                   const uint32_t overflow)
13169{
13170    m_new_inst_cpsr = m_opcode_cpsr;
13171    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13172    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13173    if (carry != ~0u)
13174        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13175    if (overflow != ~0u)
13176        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13177    if (m_new_inst_cpsr != m_opcode_cpsr)
13178    {
13179        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13180            return false;
13181    }
13182    return true;
13183}
13184
13185bool
13186EmulateInstructionARM::EvaluateInstruction ()
13187{
13188    // Advance the ITSTATE bits to their values for the next instruction.
13189    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13190        m_it_session.ITAdvance();
13191
13192
13193    ARMOpcode *opcode_data;
13194
13195    if (m_opcode_mode == eModeThumb)
13196        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32());
13197    else if (m_opcode_mode == eModeARM)
13198        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32());
13199    else
13200        return false;
13201
13202    if (!opcode_data)
13203        return false;
13204    // Verify that we're the right arch for this opcode
13205
13206    switch (m_arm_isa)
13207    {
13208    case ARMv4:
13209        if (opcode_data->variants != ARMvAll)
13210            return false;
13211        break;
13212
13213    case ARMv4T:
13214        if ((opcode_data->variants!= ARMvAll)
13215            && (opcode_data->variants != ARMV4T_ABOVE))
13216            return false;
13217        break;
13218
13219    case ARMv5T:
13220    case ARMv5TE:
13221        if ((opcode_data->variants != ARMvAll)
13222            && (opcode_data->variants != ARMV4T_ABOVE)
13223            && (opcode_data->variants != ARMV5_ABOVE))
13224            return false;
13225        break;
13226
13227    case ARMv5TEJ:
13228        if ((opcode_data->variants != ARMvAll)
13229            && (opcode_data->variants != ARMV4T_ABOVE)
13230            && (opcode_data->variants != ARMV5_ABOVE)
13231            && (opcode_data->variants != ARMV5J_ABOVE))
13232            return false;
13233        break;
13234
13235    case ARMv6:
13236    case ARMv6K:
13237        if ((opcode_data->variants != ARMvAll)
13238            && (opcode_data->variants != ARMV4T_ABOVE)
13239            && (opcode_data->variants != ARMV5_ABOVE)
13240            && (opcode_data->variants != ARMV5J_ABOVE)
13241            && (opcode_data->variants != ARMV6_ABOVE))
13242            return false;
13243        break;
13244
13245    case ARMv6T2:
13246    case ARMv7:
13247    case ARMv8:
13248        if ((opcode_data->variants != ARMvAll)
13249            && (opcode_data->variants != ARMV4T_ABOVE)
13250            && (opcode_data->variants != ARMV5_ABOVE)
13251            && (opcode_data->variants != ARMV5J_ABOVE)
13252            && (opcode_data->variants != ARMV6_ABOVE)
13253            && (opcode_data->variants != ARMV6T2_ABOVE))
13254            return false;
13255        break;
13256
13257    default:
13258//            if (opcode_data->variants != ARMvAll)
13259//                return false;
13260        break;
13261    }
13262
13263    // Just for now, for testing purposes.
13264    if (m_baton == NULL)
13265        fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(),
13266                 opcode_data->name);
13267
13268    bool success;
13269    if (m_baton)
13270    {
13271        uint32_t cpsr_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
13272        if (success)
13273            m_opcode_cpsr = cpsr_value;
13274    }
13275
13276    uint32_t orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13277    if (!success)
13278        return false;
13279
13280    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);  // Call the Emulate... function.
13281    if (!success)
13282        return false;
13283
13284    uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13285    if (!success)
13286        return false;
13287
13288    if (m_advance_pc && (after_pc_value == orig_pc_value))
13289    {
13290        if (opcode_data->size == eSize32)
13291            after_pc_value += 4;
13292        else if (opcode_data->size == eSize16)
13293            after_pc_value += 2;
13294
13295        EmulateInstruction::Context context;
13296        context.type = eContextAdvancePC;
13297        context.SetNoArgs();
13298        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13299            return false;
13300
13301    }
13302
13303    return true;
13304}
13305