EmulateInstructionARM.cpp revision 688926f8fb9a56964249ec970b4ae313a5b366d4
164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton//
364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton//                     The LLVM Compiler Infrastructure
464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton//
564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// This file is distributed under the University of Illinois Open Source
664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// License. See LICENSE.TXT for details.
764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton//
864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton//===----------------------------------------------------------------------===//
964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
10fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#include <stdlib.h>
11fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
1264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#include "EmulateInstructionARM.h"
13395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton#include "lldb/Core/ArchSpec.h"
148482dedc1d0fb4669d1ec63ec259d1cb8eaeb20fGreg Clayton#include "lldb/Core/ConstString.h"
158482dedc1d0fb4669d1ec63ec259d1cb8eaeb20fGreg Clayton
16f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Plugins/Process/Utility/ARMDefines.h"
17f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Plugins/Process/Utility/ARMUtils.h"
18f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Utility/ARM_DWARF_Registers.h"
19f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton
209b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
21930704795c783e5bf1768a43da6f957108b40873Johnny Chen                                     // and CountTrailingZeros_32 function
2264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2364c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonusing namespace lldb;
2464c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonusing namespace lldb_private;
2564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
26e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// Convenient macro definitions.
27e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#define APSR_C Bit32(m_inst_cpsr, CPSR_C)
28e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#define APSR_V Bit32(m_inst_cpsr, CPSR_V)
29e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
30f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
31f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
320e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
330e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
340e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// ITSession implementation
350e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
360e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen
38930704795c783e5bf1768a43da6f957108b40873Johnny Chen// A8.6.50
39930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
40930704795c783e5bf1768a43da6f957108b40873Johnny Chenstatic unsigned short CountITSize(unsigned ITMask) {
41930704795c783e5bf1768a43da6f957108b40873Johnny Chen    // First count the trailing zeros of the IT mask.
42930704795c783e5bf1768a43da6f957108b40873Johnny Chen    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
43930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (TZ > 3)
44930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
45930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT Mask '0000'\n");
46930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return 0;
47930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
48930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return (4 - TZ);
49930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
50930704795c783e5bf1768a43da6f957108b40873Johnny Chen
51930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Init ITState.  Note that at least one bit is always 1 in mask.
52930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InitIT(unsigned short bits7_0)
53930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
54930704795c783e5bf1768a43da6f957108b40873Johnny Chen    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
55930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (ITCounter == 0)
56930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
57930704795c783e5bf1768a43da6f957108b40873Johnny Chen
58930704795c783e5bf1768a43da6f957108b40873Johnny Chen    // A8.6.50 IT
59930704795c783e5bf1768a43da6f957108b40873Johnny Chen    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
60930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (FirstCond == 0xF)
61930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
62930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT FirstCond '1111'\n");
63930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
64930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
65930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (FirstCond == 0xE && ITCounter != 1)
66930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
67930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
68930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
69930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
70930704795c783e5bf1768a43da6f957108b40873Johnny Chen
71930704795c783e5bf1768a43da6f957108b40873Johnny Chen    ITState = bits7_0;
72930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return true;
73930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
74930704795c783e5bf1768a43da6f957108b40873Johnny Chen
75930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Update ITState if necessary.
76930704795c783e5bf1768a43da6f957108b40873Johnny Chenvoid ITSession::ITAdvance()
77930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
78930704795c783e5bf1768a43da6f957108b40873Johnny Chen    assert(ITCounter);
79930704795c783e5bf1768a43da6f957108b40873Johnny Chen    --ITCounter;
80930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (ITCounter == 0)
81930704795c783e5bf1768a43da6f957108b40873Johnny Chen        ITState = 0;
82930704795c783e5bf1768a43da6f957108b40873Johnny Chen    else
83930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
84930704795c783e5bf1768a43da6f957108b40873Johnny Chen        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
85930704795c783e5bf1768a43da6f957108b40873Johnny Chen        SetBits32(ITState, 4, 0, NewITState4_0);
86930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
87930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
88930704795c783e5bf1768a43da6f957108b40873Johnny Chen
89930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Return true if we're inside an IT Block.
90930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InITBlock()
91930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
92930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return ITCounter != 0;
93930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
94930704795c783e5bf1768a43da6f957108b40873Johnny Chen
95c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// Return true if we're the last instruction inside an IT Block.
96c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool ITSession::LastInITBlock()
97c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{
98c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    return ITCounter == 1;
99c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen}
100c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
101930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Get condition bits for the current thumb instruction.
102930704795c783e5bf1768a43da6f957108b40873Johnny Chenuint32_t ITSession::GetCond()
103930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
104c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (InITBlock())
105c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return Bits32(ITState, 7, 4);
106c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    else
107c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return COND_AL;
108930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
109930704795c783e5bf1768a43da6f957108b40873Johnny Chen
11064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// ARM constants used during decoding
11164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define REG_RD          0
11264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define LDM_REGLIST     1
113e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define SP_REG          13
114e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define LR_REG          14
11564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REG          15
11664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REGLIST_BIT  0x8000
11764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
118251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv4     (1u << 0)
11964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv4T    (1u << 1)
12064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5T    (1u << 2)
12164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TE   (1u << 3)
12264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TEJ  (1u << 4)
123251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv6     (1u << 5)
12464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6K    (1u << 6)
12564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6T2   (1u << 7)
126251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv7     (1u << 8)
12760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen#define ARMv8     (1u << 9)
12864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMvAll   (0xffffffffu)
12964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
1319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
1329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
1332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
1340e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
1350e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
1360e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation
1370e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
1380e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
1390e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen
1402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid
1412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize ()
1427dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{
1432b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen
1452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid
1462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate ()
14764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
1482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
150fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
151fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool
152fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
153fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{
1549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
1559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
1569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
157fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
158fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    uint32_t random_data = rand ();
159fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    const uint32_t addr_byte_size = GetAddressByteSize();
160fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
161cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice    if (!MemAWrite (context, address, random_data, addr_byte_size))
162fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        return false;
163fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
164fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    return true;
165fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice}
166fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
167713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
168713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool
169713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n)
170713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{
1719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
1729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
1739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
174713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
17562ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen    bool success;
176713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
177713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
178713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!success)
179713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
180713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
181713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
182713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
183713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
184713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    return true;
185713c2665a27096b68f3f8956222375354f1292f8Caroline Tice}
186713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
18708c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to
18808c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates
18908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data.
1902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
1919f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulatePUSH (ARMEncoding encoding)
19264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
19364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0
19464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    // ARM pseudo code...
19564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (ConditionPassed())
19664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
19764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        EncodingSpecificOperations();
19864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        NullCheckIfThumbEE(13);
19964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        address = SP - 4*BitCount(registers);
20064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
20164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        for (i = 0 to 14)
20264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
20364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (registers<i> == ’1’)
20464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
20564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
20664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    MemA[address,4] = bits(32) UNKNOWN;
20764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                else
20864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    MemA[address,4] = R[i];
20964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                address = address + 4;
21064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
21164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
21264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
21364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (registers<15> == ’1’) // Only possible for encoding A1 or A2
21464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            MemA[address,4] = PCStoreValue();
21564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
21664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        SP = SP - 4*BitCount(registers);
21764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
21864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif
21964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
22064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool success = false;
2212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
22264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (!success)
22364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
22464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
22664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
2272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
228e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
22964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (!success)
23064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            return false;
2313c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        uint32_t registers = 0;
23291d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        uint32_t Rt; // the source register
2333c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        switch (encoding) {
234aedde1c6a33b123031499800f56954adc86058f5Johnny Chen        case eEncodingT1:
235108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 7, 0);
236aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            // The M bit represents LR.
237bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (Bit32(opcode, 8))
238ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                registers |= (1u << 14);
239aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            // if BitCount(registers) < 1 then UNPREDICTABLE;
240aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            if (BitCount(registers) < 1)
241aedde1c6a33b123031499800f56954adc86058f5Johnny Chen                return false;
242aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            break;
2437dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen        case eEncodingT2:
2447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // Ignore bits 15 & 13.
245108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 15, 0) & ~0xa000;
2467dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if BitCount(registers) < 2 then UNPREDICTABLE;
2477dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            if (BitCount(registers) < 2)
2487dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen                return false;
2497dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            break;
2507dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen        case eEncodingT3:
251108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
2527dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if BadReg(t) then UNPREDICTABLE;
25391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            if (BadReg(Rt))
2547dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen                return false;
25591d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            registers = (1u << Rt);
2567dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            break;
2573c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        case eEncodingA1:
258108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 15, 0);
259a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // Instead of return false, let's handle the following case as well,
260a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // which amounts to pushing one reg onto the full descending stacks.
261a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
2623c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen            break;
2633c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        case eEncodingA2:
264108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
2657dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if t == 13 then UNPREDICTABLE;
26691d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            if (Rt == dwarf_sp)
2673c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen                return false;
26891d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            registers = (1u << Rt);
2693c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen            break;
270ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        default:
271ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
2723c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        }
273ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t sp_offset = addr_byte_size * BitCount (registers);
27464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        addr_t addr = sp - sp_offset;
27564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        uint32_t i;
27664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
2789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPushRegisterOnStack;
2799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
2809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
28164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        for (i=0; i<15; ++i)
28264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
2837c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen            if (BitIsSet (registers, i))
28464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
2859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                dwarf_reg.num = dwarf_r0 + i;
2869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
287e39f22d1a369866808b8739c3cec15063d806833Johnny Chen                uint32_t reg_value = ReadCoreReg(i, &success);
28864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if (!success)
28964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    return false;
290cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
29164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    return false;
29264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                addr += addr_byte_size;
29364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
29464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
29564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2967c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen        if (BitIsSet (registers, 15))
29764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
2989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_pc;
2999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
300e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            const uint32_t pc = ReadCoreReg(PC_REG, &success);
30164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (!success)
30264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                return false;
303e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            if (!MemAWrite (context, addr, pc, addr_byte_size))
30464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                return false;
30564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
30664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
30764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        context.type = EmulateInstruction::eContextAdjustStackPointer;
3089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
30964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
3102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
31164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            return false;
31264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
31364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return true;
31464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
31564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
316ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from
317ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates
318ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data.
3192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
3209f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulatePOP (ARMEncoding encoding)
321ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{
322ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0
323ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    // ARM pseudo code...
324ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    if (ConditionPassed())
325ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    {
326ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
327ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        address = SP;
328ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        for i = 0 to 14
329ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if registers<i> == ‘1then
330ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
331ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if registers<15> == ‘1then
332ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if UnalignedAllowed then
333ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                LoadWritePC(MemU[address,4]);
334ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            else
335ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                LoadWritePC(MemA[address,4]);
336ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers);
337ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if registers<13> == ‘1then SP = bits(32) UNKNOWN;
338ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    }
339ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif
340ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
341ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    bool success = false;
3422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
343ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    if (!success)
344ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        return false;
345ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
3462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
347ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    {
3482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
349e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
350ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if (!success)
351ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
352ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t registers = 0;
353ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t Rt; // the destination register
354ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        switch (encoding) {
355ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT1:
356ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 7, 0);
357ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // The P bit represents PC.
358bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (Bit32(opcode, 8))
359ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                registers |= (1u << 15);
360ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(registers) < 1 then UNPREDICTABLE;
361ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (BitCount(registers) < 1)
362ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
363ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
364ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT2:
365ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // Ignore bit 13.
366ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 15, 0) & ~0x2000;
367ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
368bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
369ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
370098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
371098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
372098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                return false;
373ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
374ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT3:
375ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            Rt = Bits32(opcode, 15, 12);
376ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
377098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 13)
378098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                return false;
379098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 15 && InITBlock() && !LastInITBlock())
380ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
381ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = (1u << Rt);
382ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
383ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingA1:
384ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 15, 0);
385ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // Instead of return false, let's handle the following case as well,
386ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // which amounts to popping one reg from the full descending stacks.
387ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
388ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
389ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE;
390098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
391ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
392ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
393ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingA2:
394ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            Rt = Bits32(opcode, 15, 12);
395ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if t == 13 then UNPREDICTABLE;
396ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (Rt == dwarf_sp)
397ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
398ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = (1u << Rt);
399ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
400ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        default:
401ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
402ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
403ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        addr_t sp_offset = addr_byte_size * BitCount (registers);
404ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        addr_t addr = sp;
405ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t i, data;
406ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
4089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPopRegisterOffStack;
4099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
4109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
411ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        for (i=0; i<15; ++i)
412ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        {
4137c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen            if (BitIsSet (registers, i))
414ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            {
4159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                dwarf_reg.num = dwarf_r0 + i;
4169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
417cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                data = MemARead(context, addr, 4, 0, &success);
418ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                if (!success)
419ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                    return false;
4209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
421ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                    return false;
422ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                addr += addr_byte_size;
423ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            }
424ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
425ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4267c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen        if (BitIsSet (registers, 15))
427ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        {
4289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_pc;
4299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
430cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            data = MemARead(context, addr, 4, 0, &success);
431ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (!success)
432ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
433f3eaacfc02d0a98d3bac1eaef74ad5c1c66ccfdcJohnny Chen            // In ARMv5T and above, this is an interworking branch.
434668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
435ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
436ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            addr += addr_byte_size;
437ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
438ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
439ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
4409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
441ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
443ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
444ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    }
445ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    return true;
446ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen}
447ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4485b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// Set r7 or ip to point to saved value residing within the stack.
449bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen// ADD (SP plus immediate)
4502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
4519f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateADDRdSPImm (ARMEncoding encoding)
452bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{
453bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0
454bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    // ARM pseudo code...
455bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    if (ConditionPassed())
456bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    {
457bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        EncodingSpecificOperations();
458bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
459bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        if d == 15 then
460bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
461bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        else
462bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            R[d] = result;
463bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            if setflags then
464bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.N = result<31>;
465bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.Z = IsZeroBit(result);
466bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.C = carry;
467bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.V = overflow;
468bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    }
469bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#endif
470bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
471bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    bool success = false;
4722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
473bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    if (!success)
474bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        return false;
475bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
4762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
477bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    {
478e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
479bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        if (!success)
480bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
481bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        uint32_t Rd; // the destination register
482bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        uint32_t imm32;
483bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        switch (encoding) {
484bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        case eEncodingT1:
485bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            Rd = 7;
486bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
487bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            break;
488bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        case eEncodingA1:
489bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            Rd = Bits32(opcode, 15, 12);
490bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
491bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            break;
492bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        default:
493bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
494bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        }
495bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        addr_t sp_offset = imm32;
496bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        addr_t addr = sp + sp_offset; // a pointer to the stack area
497bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
4989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
4999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
5009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register sp_reg;
5019bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
5029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (sp_reg, sp_offset);
503bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
5042b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
505bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
506bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    }
507bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    return true;
508bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen}
509bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
5102ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer.
5112ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register)
5122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
5139f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdSP (ARMEncoding encoding)
5142ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{
5152ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0
5162ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    // ARM pseudo code...
5172ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    if (ConditionPassed())
5182ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    {
5192ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        EncodingSpecificOperations();
5202ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        result = R[m];
5212ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        if d == 15 then
5222ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
5232ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        else
5242ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            R[d] = result;
5252ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            if setflags then
5262ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                APSR.N = result<31>;
5272ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                APSR.Z = IsZeroBit(result);
5282ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                // APSR.C unchanged
5292ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                // APSR.V unchanged
5302ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    }
5312ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif
5322ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5332ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    bool success = false;
5342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    //const uint32_t opcode = OpcodeAsUnsigned (&success);
5351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    //if (!success)
5361c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    //    return false;
5372ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
5392ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    {
540e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
5412ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        if (!success)
5422ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
5432ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        uint32_t Rd; // the destination register
5442ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        switch (encoding) {
5452ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        case eEncodingT1:
5462ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            Rd = 7;
5472ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            break;
5482ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        case eEncodingA1:
5492ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            Rd = 12;
5502ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            break;
5512ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        default:
5522ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
5532ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        }
5549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
5559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
5569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
5579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register sp_reg;
5589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
5599bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (sp_reg, 0);
5602ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
5622ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
5632ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    }
5642ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    return true;
5652ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen}
5662ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5671c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7).
5681c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register)
5692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
5709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVLowHigh (ARMEncoding encoding)
5711c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{
5729f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen    return EmulateMOVRdRm (encoding);
573338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen}
574338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen
575338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register.
576338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register)
577338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool
5789f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdRm (ARMEncoding encoding)
579338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{
5801c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0
5811c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    // ARM pseudo code...
5821c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    if (ConditionPassed())
5831c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    {
5841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        EncodingSpecificOperations();
5851c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        result = R[m];
5861c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        if d == 15 then
5871c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
5881c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        else
5891c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            R[d] = result;
5901c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            if setflags then
5911c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                APSR.N = result<31>;
5921c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                APSR.Z = IsZeroBit(result);
5931c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                // APSR.C unchanged
5941c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                // APSR.V unchanged
5951c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    }
5961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif
5971c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
5981c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    bool success = false;
5992b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
6001c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    if (!success)
6011c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        return false;
6021c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
6032b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
6041c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    {
6051c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        uint32_t Rm; // the source register
6061c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        uint32_t Rd; // the destination register
607338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        bool setflags;
6081c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        switch (encoding) {
6091c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        case eEncodingT1:
6107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
6111c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            Rm = Bits32(opcode, 6, 3);
612338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            setflags = false;
6137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rd == 15 && InITBlock() && !LastInITBlock())
6147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
615338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            break;
616338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        case eEncodingT2:
6177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 2, 0);
618338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            Rm = Bits32(opcode, 5, 3);
619338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            setflags = true;
6207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (InITBlock())
6217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
6221c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            break;
6237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT3:
6247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
6257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 3, 0);
6267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
6277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
6287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (setflags && (BadReg(Rd) || BadReg(Rm)))
6297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
6307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
6317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
6327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
6331c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        default:
6341c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            return false;
6351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        }
6367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t result = ReadCoreReg(Rm, &success);
6371c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        if (!success)
6381c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            return false;
6391c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
6401c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        // The context specifies that Rm is to be moved into Rd.
6419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
6429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
6439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
6449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
6459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, 0);
646ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
64710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
648ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
6491c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    }
6501c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    return true;
6511c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen}
6521c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
653357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register.  It
654357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value.
655357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate)
656357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool
6579f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdImm (ARMEncoding encoding)
658357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{
659357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0
660357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    // ARM pseudo code...
661357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (ConditionPassed())
662357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    {
663357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        EncodingSpecificOperations();
664357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        result = imm32;
665357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
666357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
667357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        else
668357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            R[d] = result;
669357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            if setflags then
670357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.N = result<31>;
671357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.Z = IsZeroBit(result);
672357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.C = carry;
673357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                // APSR.V unchanged
674357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    }
675357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif
676357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    bool success = false;
677357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
678357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (!success)
679357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        return false;
680357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
681357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (ConditionPassed())
682357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    {
683357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t Rd; // the destination register
684357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm32; // the immediate value to be written to Rd
685357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
686357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        bool setflags;
687357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        switch (encoding) {
688357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        case eEncodingT1:
6897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 10, 8);
690357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            setflags = !InITBlock();
691357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
692e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            carry = APSR_C;
693357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            break;
694357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        case eEncodingT2:
6957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
696357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            setflags = BitIsSet(opcode, 20);
6977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
6989798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen            if (BadReg(Rd))
6999798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen                return false;
700357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            break;
701357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        default:
702357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            return false;
703357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        }
704357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t result = imm32;
705357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
706357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        // The context specifies that an immediate is to be moved into Rd.
7079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
7089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
7099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
710ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
71110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
712ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
713357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    }
714357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    return true;
715357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen}
716357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
717d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
718d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the value.
71928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool
720d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny ChenEmulateInstructionARM::EmulateMVNImm (ARMEncoding encoding)
72128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{
72228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0
72328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    // ARM pseudo code...
72428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    if (ConditionPassed())
72528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    {
72628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        EncodingSpecificOperations();
72728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        result = NOT(imm32);
72828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
72928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
73028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        else
73128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            R[d] = result;
73228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            if setflags then
73328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.N = result<31>;
73428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.Z = IsZeroBit(result);
73528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.C = carry;
73628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                // APSR.V unchanged
73728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    }
73828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif
73933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    bool success = false;
74033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
74133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    if (!success)
74233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        return false;
74333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen
74433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    if (ConditionPassed())
74533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    {
74633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        uint32_t Rd; // the destination register
747357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
748357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
74933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        bool setflags;
75033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        switch (encoding) {
75133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        case eEncodingT1:
75233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            Rd = Bits32(opcode, 11, 8);
75333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            setflags = BitIsSet(opcode, 20);
754d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
75533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            break;
75633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        case eEncodingA1:
75733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            Rd = Bits32(opcode, 15, 12);
75833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            setflags = BitIsSet(opcode, 20);
759d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
760d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
761d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
762d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if (Rd == 15 && setflags)
763d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                return false;
76433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            break;
76533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        default:
76633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            return false;
76733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        }
76833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        uint32_t result = ~imm32;
76933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen
77033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
7719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
7729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
7739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
774ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
77510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
776ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
77733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    }
77833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    return true;
77928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen}
78028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen
781d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
782d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the result.
783d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chenbool
784d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny ChenEmulateInstructionARM::EmulateMVNReg (ARMEncoding encoding)
785d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen{
786d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#if 0
787d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    // ARM pseudo code...
788d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    if (ConditionPassed())
789d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    {
790d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        EncodingSpecificOperations();
791d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
792d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        result = NOT(shifted);
793d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
794d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
795d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        else
796d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            R[d] = result;
797d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if setflags then
798d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                APSR.N = result<31>;
799d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                APSR.Z = IsZeroBit(result);
800d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                APSR.C = carry;
801d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                // APSR.V unchanged
802d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    }
803d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#endif
804d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
805d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    bool success = false;
806d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
807d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    if (!success)
808d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        return false;
809d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
810d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    if (ConditionPassed())
811d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    {
812d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t Rm; // the source register
813d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t Rd; // the destination register
814d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        ARM_ShifterType shift_t;
815d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
816d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        bool setflags;
817d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t carry; // the carry bit after the shift operation
818d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        switch (encoding) {
819d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        case eEncodingT1:
820d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rd = Bits32(opcode, 2, 0);
821d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rm = Bits32(opcode, 5, 3);
822d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            setflags = !InITBlock();
823d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            shift_t = SRType_LSL;
824d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            shift_n = 0;
825d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if (InITBlock())
826d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                return false;
827d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            break;
828d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        case eEncodingT2:
829d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rd = Bits32(opcode, 11, 8);
830d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rm = Bits32(opcode, 3, 0);
831d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            setflags = BitIsSet(opcode, 20);
832d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
833d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
834d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if ((BadReg(Rd) || BadReg(Rm)))
835d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                return false;
836d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        case eEncodingA1:
837d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rd = Bits32(opcode, 15, 12);
838d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rm = Bits32(opcode, 3, 0);
839d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            setflags = BitIsSet(opcode, 20);
840d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
841d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            break;
842d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        default:
843d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            return false;
844d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        }
845d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t value = ReadCoreReg(Rm, &success);
846d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        if (!success)
847d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            return false;
848d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
849d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry);
850d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t result = ~shifted;
851d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
852d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // The context specifies that an immediate is to be moved into Rd.
853d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        EmulateInstruction::Context context;
854d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
855d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        context.SetNoArgs ();
856d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
857d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
858d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            return false;
859d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    }
860d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    return true;
861d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen}
862d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
863788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register).
864788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal)
8652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
866c9de910d61f0471d18fced716fc10681ef432010Johnny ChenEmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding)
867788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{
868788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0
869788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    // ARM pseudo code...
870788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    if (ConditionPassed())
871788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    {
872788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
873788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        base = Align(PC,4);
874788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        address = if add then (base + imm32) else (base - imm32);
875788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        data = MemU[address,4];
876788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if t == 15 then
877788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE;
878788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        elsif UnalignedSupport() || address<1:0> = ‘00’ then
879788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            R[t] = data;
880788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        else // Can only apply before ARMv7
881788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            if CurrentInstrSet() == InstrSet_ARM then
882788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen                R[t] = ROR(data, 8*UInt(address<1:0>));
883788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            else
884788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen                R[t] = bits(32) UNKNOWN;
885788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    }
886788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif
887788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
888788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    bool success = false;
8892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
890788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    if (!success)
891788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        return false;
892788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
8932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
894788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    {
895e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
896788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if (!success)
897788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
898809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen
899809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen        // PC relative immediate load context
9009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
9019bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
9029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register pc_reg;
9039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
9049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (pc_reg, 0);
9059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
906c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        uint32_t Rt;    // the destination register
907788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        uint32_t imm32; // immediate offset from the PC
908c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        bool add;       // +imm32 or -imm32?
909c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        addr_t base;    // the base address
910c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        addr_t address; // the PC relative address
911788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        uint32_t data;  // the literal data value from the PC relative load
912788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        switch (encoding) {
913788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        case eEncodingT1:
914c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            Rt = Bits32(opcode, 10, 8);
915788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
916c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            add = true;
917c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            break;
918c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        case eEncodingT2:
919c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            Rt = Bits32(opcode, 15, 12);
920c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
921c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            add = BitIsSet(opcode, 23);
922098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 15 && InITBlock() && !LastInITBlock())
923c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
924788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            break;
925788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        default:
926788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
927788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        }
928c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
929e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        base = Align(pc, 4);
930c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (add)
931c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            address = base + imm32;
932c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else
933c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            address = base - imm32;
934e39f22d1a369866808b8739c3cec15063d806833Johnny Chen
935e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        context.SetRegisterPlusOffset(pc_reg, address - base);
936cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        data = MemURead(context, address, 4, 0, &success);
937788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if (!success)
938809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen            return false;
939c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
940c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (Rt == 15)
941c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        {
942c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            if (Bits32(address, 1, 0) == 0)
943c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            {
944c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                // In ARMv5T and above, this is an interworking branch.
945668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen                if (!LoadWritePC(context, data))
946c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                    return false;
947c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            }
948c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            else
949c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
950c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        }
951c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
952c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        {
953c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
954c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
955c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        }
956c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else // We don't handle ARM for now.
957c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            return false;
958c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
959c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
960788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
961788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    }
962788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    return true;
963788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen}
964788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
9655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP.
966fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate)
9672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
968864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateADDSPImm (ARMEncoding encoding)
969fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{
970fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0
971fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    // ARM pseudo code...
972fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    if (ConditionPassed())
973fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    {
974fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        EncodingSpecificOperations();
975fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
976fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        if d == 15 then // Can only occur for ARM encoding
977fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
978fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        else
979fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            R[d] = result;
980fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            if setflags then
981fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.N = result<31>;
982fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.Z = IsZeroBit(result);
983fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.C = carry;
984fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.V = overflow;
985fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    }
986fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif
987fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
988fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    bool success = false;
9892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
990fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    if (!success)
991fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        return false;
992fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
9932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
994fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    {
995e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
996fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        if (!success)
997fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
998fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        uint32_t imm32; // the immediate operand
999fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        switch (encoding) {
1000fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        case eEncodingT2:
1001fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1002fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            break;
1003fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        default:
1004fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
1005fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        }
1006fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        addr_t sp_offset = imm32;
1007fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1008fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
10099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
10109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
10119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
1012fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
10132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1014fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
1015fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    }
1016fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    return true;
1017fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen}
1018fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
1019fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP.
10205b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register)
10212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
1022864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateADDSPRm (ARMEncoding encoding)
10235b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{
10245b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0
10255b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    // ARM pseudo code...
10265b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    if (ConditionPassed())
10275b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    {
10285b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        EncodingSpecificOperations();
10295b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
10305b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’);
10315b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if d == 15 then
10325b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
10335b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        else
10345b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            R[d] = result;
10355b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            if setflags then
10365b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.N = result<31>;
10375b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.Z = IsZeroBit(result);
10385b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.C = carry;
10395b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.V = overflow;
10405b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    }
10415b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif
10425b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
10435b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    bool success = false;
10442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
10455b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    if (!success)
10465b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        return false;
10475b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
10482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
10495b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    {
1050e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
10515b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if (!success)
10525b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
10535b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        uint32_t Rm; // the second operand
10545b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        switch (encoding) {
10555b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        case eEncodingT2:
10565b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            Rm = Bits32(opcode, 6, 3);
10575b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            break;
10585b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        default:
10595b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
10605b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        }
1061e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        int32_t reg_value = ReadCoreReg(Rm, &success);
10625b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if (!success)
10635b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
10645b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
10655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
10665b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
10679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
10689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
10699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (reg_value);
10705b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
10712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
10725b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
10735b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    }
10745b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    return true;
10755b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen}
10765b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
10779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
10789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or
10799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM.
10809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate)
10819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool
10829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny ChenEmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding)
10839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{
10849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0
10859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    // ARM pseudo code...
10869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
10879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
10889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        EncodingSpecificOperations();
10899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if CurrentInstrSet() == InstrSet_ARM then
10909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = PC - 4;
10919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
10929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = PC<31:1> : '1';
10939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if targetInstrSet == InstrSet_ARM then
10949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            targetAddress = Align(PC,4) + imm32;
10959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
10969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            targetAddress = PC + imm32;
10979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        SelectInstrSet(targetInstrSet);
10989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        BranchWritePC(targetAddress);
10999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
11009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif
11019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
11029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    bool success = false;
11039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
11049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (!success)
11059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        return false;
11069b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
11079b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
11089b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
11099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
11109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1111e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
11129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!success)
11139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
111453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t lr; // next instruction address
111553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t target; // target address
11169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        int32_t imm32; // PC-relative offset
11179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        switch (encoding) {
1118d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        case eEncodingT1:
1119d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            {
1120e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = pc | 1u; // return address
1121bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
1122d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t imm10 = Bits32(opcode, 25, 16);
1123bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1124bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
1125d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
1126d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t I1 = !(J1 ^ S);
1127d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t I2 = !(J2 ^ S);
112853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1129d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1130e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
11319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1132098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1133ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
1134d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            break;
1135d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            }
11369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingT2:
11379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            {
1138e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = pc | 1u; // return address
1139bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
11409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t imm10H = Bits32(opcode, 25, 16);
1141bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1142bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
11439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t imm10L = Bits32(opcode, 10, 1);
11449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t I1 = !(J1 ^ S);
11459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t I2 = !(J2 ^ S);
114653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
11479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1148e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = Align(pc, 4) + imm32;
11499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1150098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1151ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
11529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
11539b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            }
1154c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen        case eEncodingA1:
1155c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            lr = pc + 4; // return address
1156c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1157e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = Align(pc, 4) + imm32;
11589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1159c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            break;
11609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingA2:
11619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            lr = pc + 4; // return address
11629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1163e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
11649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
11659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
11669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        default:
11679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
11689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        }
11699b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
11709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
11719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!BranchWritePC(context, target))
11729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
11739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
11749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    return true;
11759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen}
11769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
11779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and
11789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register.
11799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register)
11809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool
11819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny ChenEmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding)
11829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{
11839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0
11849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    // ARM pseudo code...
11859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
11869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
11879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        EncodingSpecificOperations();
11889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        target = R[m];
11899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if CurrentInstrSet() == InstrSet_ARM then
11909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            next_instr_addr = PC - 4;
11919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = next_instr_addr;
11929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
11939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            next_instr_addr = PC - 2;
11949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = next_instr_addr<31:1> : ‘1’;
11959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        BXWritePC(target);
11969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
11979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif
11989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
11999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    bool success = false;
12009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
12019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (!success)
12029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        return false;
12039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
12049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
12059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
12069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
12079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1208e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
12099b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        addr_t lr; // next instruction address
12109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!success)
12119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
12129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        uint32_t Rm; // the register with the target address
12139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        switch (encoding) {
12149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingT1:
1215e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = (pc - 2) | 1u; // return address
12169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            Rm = Bits32(opcode, 6, 3);
12179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            // if m == 15 then UNPREDICTABLE;
12189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            if (Rm == 15)
12199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen                return false;
1220098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1221ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
12229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
12239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingA1:
1224e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = pc - 4; // return address
12259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            Rm = Bits32(opcode, 3, 0);
12269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            // if m == 15 then UNPREDICTABLE;
12279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            if (Rm == 15)
12289b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen                return false;
1229b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
12309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        default:
12319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
12329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        }
1233e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        addr_t target = ReadCoreReg (Rm, &success);
1234ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        if (!success)
1235ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
12369bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
12379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
12389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegister (dwarf_reg);
12399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
12409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
1241668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        if (!BXWritePC(context, target))
12429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
12439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
12449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    return true;
12459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen}
12469b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
1247ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1248ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// BX
1249ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool
1250ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny ChenEmulateInstructionARM::EmulateBXRm (ARMEncoding encoding)
1251ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{
1252ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0
1253ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    // ARM pseudo code...
1254ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (ConditionPassed())
1255ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    {
1256ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        EncodingSpecificOperations();
1257ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        BXWritePC(R[m]);
1258ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    }
1259ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif
1260ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
1261ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    bool success = false;
1262ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1263ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (!success)
1264ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        return false;
1265ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
1266ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (ConditionPassed())
1267ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    {
12689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
12699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1270ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        uint32_t Rm; // the register with the target address
1271ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        switch (encoding) {
1272ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        case eEncodingT1:
1273ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            Rm = Bits32(opcode, 6, 3);
1274098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1275ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
1276ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            break;
1277ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        case eEncodingA1:
1278ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            Rm = Bits32(opcode, 3, 0);
1279ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            break;
1280ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        default:
1281ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1282ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        }
1283e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        addr_t target = ReadCoreReg (Rm, &success);
1284ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        if (!success)
1285ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
12869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
12879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
12889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1289668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetRegister (dwarf_reg);
1290668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        if (!BXWritePC(context, target))
1291ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1292ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    }
1293ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    return true;
1294ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen}
1295ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
12960d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset.
12970d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate)
12982b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
1299864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateSUBR7IPImm (ARMEncoding encoding)
13000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{
13010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0
13020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    // ARM pseudo code...
13030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (ConditionPassed())
13040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
13050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        EncodingSpecificOperations();
13060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
13070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if d == 15 then // Can only occur for ARM encoding
13080d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
13090d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        else
13100d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            R[d] = result;
13110d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            if setflags then
13120d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.N = result<31>;
13130d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.Z = IsZeroBit(result);
13140d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.C = carry;
13150d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.V = overflow;
13160d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
13170d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif
13180d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13190d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    bool success = false;
13202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
13210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (!success)
13220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        return false;
13230d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
13250d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
1326e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t ip = ReadCoreReg (12, &success);
13270d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if (!success)
13280d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
13290d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        uint32_t imm32;
13300d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        switch (encoding) {
13310d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        case eEncodingA1:
13320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
13330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            break;
13340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        default:
13350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
13360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        }
13370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t ip_offset = imm32;
13380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t addr = ip - ip_offset; // the adjusted ip value
13390d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
13419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
13429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
13439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
13449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
13450d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
13470d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
13480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
13490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    return true;
13500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen}
13510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset.
13530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate)
13542b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
1355864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateSUBIPSPImm (ARMEncoding encoding)
13560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{
13570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0
13580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    // ARM pseudo code...
13590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (ConditionPassed())
13600d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
13610d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        EncodingSpecificOperations();
13620d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
13630d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if d == 15 then // Can only occur for ARM encoding
13640d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
13650d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        else
13660d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            R[d] = result;
13670d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            if setflags then
13680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.N = result<31>;
13690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.Z = IsZeroBit(result);
13700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.C = carry;
13710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.V = overflow;
13720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
13730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif
13740d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13750d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    bool success = false;
13762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
13770d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (!success)
13780d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        return false;
13790d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
13810d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
1382e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
13830d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if (!success)
13840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
13850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        uint32_t imm32;
13860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        switch (encoding) {
13870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        case eEncodingA1:
13880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
13890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            break;
13900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        default:
13910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
13920d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        }
13930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t sp_offset = imm32;
13940d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
13950d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
13979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
13989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
13999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
14009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
14010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
14022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
14030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
14040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
14050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    return true;
14060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen}
14070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
14084c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen// A sub operation to adjust the SP -- allocate space for local storage.
14092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
1410864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny ChenEmulateInstructionARM::EmulateSUBSPImm (ARMEncoding encoding)
14114c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{
14124c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0
14134c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    // ARM pseudo code...
14144c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    if (ConditionPassed())
14154c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    {
14164c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        EncodingSpecificOperations();
14174c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
14184c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        if d == 15 then // Can only occur for ARM encoding
1419799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
14204c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        else
14214c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            R[d] = result;
14224c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            if setflags then
14234c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.N = result<31>;
14244c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.Z = IsZeroBit(result);
14254c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.C = carry;
14264c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.V = overflow;
14274c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    }
14284c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif
14294c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
14304c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    bool success = false;
14312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
14324c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    if (!success)
14334c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        return false;
14344c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
14352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
14364c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    {
1437e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
14384c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        if (!success)
14394c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
14404c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        uint32_t imm32;
14414c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        switch (encoding) {
1442e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen        case eEncodingT1:
1443e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
144460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen        case eEncodingT2:
144560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
144660c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            break;
144760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen        case eEncodingT3:
144860c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
144960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            break;
14504c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        case eEncodingA1:
145160c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
14524c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            break;
14534c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        default:
14544c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
14554c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        }
14564c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        addr_t sp_offset = imm32;
14574c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
14584c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
14599bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
14609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
14619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
14624c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
14632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
14644c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
14654c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    }
14664c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    return true;
14674c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen}
14684c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
146908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP.
14702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
14712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding)
1472ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{
1473ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0
1474ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    // ARM pseudo code...
1475ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    if (ConditionPassed())
1476ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    {
1477ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        EncodingSpecificOperations();
1478ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1479ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        address = if index then offset_addr else R[n];
1480ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1481ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        if wback then R[n] = offset_addr;
1482ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    }
1483ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif
1484ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
1485ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    bool success = false;
14862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
1487ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    if (!success)
1488ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        return false;
1489ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
14902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
1491ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    {
14922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
1493e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
1494ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        if (!success)
1495ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
149691d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        uint32_t Rt; // the source register
1497ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        uint32_t imm12;
1498ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        switch (encoding) {
1499ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        case eEncodingA1:
1500108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
1501108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            imm12 = Bits32(opcode, 11, 0);
1502ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            break;
1503ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        default:
1504ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
1505ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1506ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t sp_offset = imm12;
1507ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t addr = sp - sp_offset;
1508ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
15099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
15109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPushRegisterOnStack;
15119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
15129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
151391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        if (Rt != 15)
1514ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        {
15159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_r0 + Rt;
15169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1517e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            uint32_t reg_value = ReadCoreReg(Rt, &success);
1518ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            if (!success)
1519ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1520cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1521ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1522ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1523ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        else
1524ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        {
15259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_pc;
15269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1527e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1528ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            if (!success)
1529ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1530cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, addr, pc + 8, addr_byte_size))
1531ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1532ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1533ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
1534ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
15359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
1536ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
15372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1538ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
1539ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    }
1540ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    return true;
1541ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen}
1542ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
154308c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack.
154408c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data.
15452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
15462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding)
1547799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{
1548799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0
1549799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    // ARM pseudo code...
1550799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    if (ConditionPassed())
1551799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    {
1552799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1553799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        address = SP - imm32;
1554799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        SP = SP - imm32;
1555799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        if single_regs then
1556799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            for r = 0 to regs-1
1557799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address,4] = S[d+r]; address = address+4;
1558799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        else
1559799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            for r = 0 to regs-1
1560799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                // Store as two word-aligned words in the correct order for current endianness.
1561799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1562799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1563799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                address = address+8;
1564799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    }
1565799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif
1566799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
1567799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    bool success = false;
15682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
1569799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    if (!success)
1570799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        return false;
1571799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
15722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
1573799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    {
15742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
1575e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
1576799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        if (!success)
1577799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
1578799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        bool single_regs;
1579587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1580799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t imm32; // stack offset
1581799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t regs;  // number of registers
1582799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        switch (encoding) {
1583799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingT1:
1584799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingA1:
1585799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            single_regs = false;
1586bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1587799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1588799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // If UInt(imm8) is odd, see "FSTMX".
1589799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            regs = Bits32(opcode, 7, 0) / 2;
1590799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1591799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1592799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1593799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            break;
1594799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingT2:
1595799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingA2:
1596799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            single_regs = true;
1597bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1598799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1599799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            regs = Bits32(opcode, 7, 0);
1600799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1601799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1602799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1603799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            break;
1604799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        default:
1605799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
1606799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        }
1607799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1608799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1609799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        addr_t sp_offset = imm32;
1610799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        addr_t addr = sp - sp_offset;
1611799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t i;
1612799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
16139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
16149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPushRegisterOnStack;
16159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
16169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1617799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        for (i=d; i<regs; ++i)
1618799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        {
16199bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = start_reg + i;
16209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset ( dwarf_reg, addr - sp);
1621799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // uint64_t to accommodate 64-bit registers.
16229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1623799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (!success)
1624799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1625cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1626799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1627799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            addr += reg_byte_size;
1628799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        }
1629799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
1630799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
16319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
1632799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
16332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1634799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
1635799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    }
1636799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    return true;
1637799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen}
1638799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
1639587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack.
1640587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data.
1641587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool
1642587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny ChenEmulateInstructionARM::EmulateVPOP (ARMEncoding encoding)
1643587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{
1644587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0
1645587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    // ARM pseudo code...
1646587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (ConditionPassed())
1647587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    {
1648587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1649587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        address = SP;
1650587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        SP = SP + imm32;
1651587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if single_regs then
1652587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            for r = 0 to regs-1
1653587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                S[d+r] = MemA[address,4]; address = address+4;
1654587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        else
1655587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            for r = 0 to regs-1
1656587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1657587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                // Combine the word-aligned words in the correct order for current endianness.
1658587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1659587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    }
1660587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif
1661587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1662587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    bool success = false;
1663587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1664587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (!success)
1665587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        return false;
1666587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1667587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (ConditionPassed())
1668587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    {
1669587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        const uint32_t addr_byte_size = GetAddressByteSize();
1670e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
1671587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if (!success)
1672587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
1673587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        bool single_regs;
1674587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1675587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t imm32; // stack offset
1676587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t regs;  // number of registers
1677587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        switch (encoding) {
1678587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingT1:
1679587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingA1:
1680587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            single_regs = false;
1681bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1682587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1683587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // If UInt(imm8) is odd, see "FLDMX".
1684587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            regs = Bits32(opcode, 7, 0) / 2;
1685587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1686587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1687587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
1688587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            break;
1689587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingT2:
1690587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingA2:
1691587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            single_regs = true;
1692bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1693587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1694587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            regs = Bits32(opcode, 7, 0);
1695587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1696587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1697587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
1698587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            break;
1699587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        default:
1700587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
1701587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        }
1702587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1703587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1704587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        addr_t sp_offset = imm32;
1705587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        addr_t addr = sp;
1706587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t i;
1707587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint64_t data; // uint64_t to accomodate 64-bit registers.
1708587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
17099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
17109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPopRegisterOffStack;
17119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
17129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1713587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        for (i=d; i<regs; ++i)
1714587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        {
17159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = start_reg + i;
17169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1717cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            data = MemARead(context, addr, reg_byte_size, 0, &success);
1718587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (!success)
1719587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
17209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
1721587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
1722587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            addr += reg_byte_size;
1723587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        }
1724587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1725587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
17269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
1727587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1728587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1729587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
1730587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    }
1731587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    return true;
1732587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen}
1733587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1734b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI)
1735b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool
1736b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny ChenEmulateInstructionARM::EmulateSVC (ARMEncoding encoding)
1737b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{
1738b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0
1739b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    // ARM pseudo code...
1740b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (ConditionPassed())
1741b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    {
1742b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        EncodingSpecificOperations();
1743b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        CallSupervisor();
1744b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    }
1745b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif
1746b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
1747b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    bool success = false;
1748b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1749b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (!success)
1750b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        return false;
1751b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
1752b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (ConditionPassed())
1753b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    {
1754e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1755b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        addr_t lr; // next instruction address
1756b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        if (!success)
1757b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
1758b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        uint32_t imm32; // the immediate constant
1759b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        uint32_t mode;  // ARM or Thumb mode
1760b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        switch (encoding) {
1761b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        case eEncodingT1:
1762b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            lr = (pc + 2) | 1u; // return address
1763b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            imm32 = Bits32(opcode, 7, 0);
1764b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            mode = eModeThumb;
1765b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
1766b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        case eEncodingA1:
1767b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            lr = pc + 4; // return address
1768b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            imm32 = Bits32(opcode, 23, 0);
1769b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            mode = eModeARM;
1770b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
1771b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        default:
1772b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
1773b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        }
17749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
17759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
17769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextSupervisorCall;
17779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetModeAndImmediate (mode, imm32);
1778b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1779b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
1780b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    }
1781b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    return true;
1782b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen}
1783b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
1784c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional.
1785c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool
1786c315f860b343cf4a143f43c7d570d151989abb46Johnny ChenEmulateInstructionARM::EmulateIT (ARMEncoding encoding)
1787c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{
1788c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0
1789c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    // ARM pseudo code...
1790c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    EncodingSpecificOperations();
1791c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    ITSTATE.IT<7:0> = firstcond:mask;
1792c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif
1793c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
1794c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    bool success = false;
1795c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1796c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (!success)
1797c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return false;
1798c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
1799c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    m_it_session.InitIT(Bits32(opcode, 7, 0));
1800c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    return true;
1801c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen}
1802c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
18033b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address.
18043b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool
18053b620b38cd170c20ea607585021ab2ab50286943Johnny ChenEmulateInstructionARM::EmulateB (ARMEncoding encoding)
18063b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{
18073b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0
18083b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    // ARM pseudo code...
18093b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    if (ConditionPassed())
18103b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    {
18113b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        EncodingSpecificOperations();
18123b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        BranchWritePC(PC + imm32);
18133b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    }
18143b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif
18153b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
18163b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    bool success = false;
18173b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
18183b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    if (!success)
18193b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        return false;
18203b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
18219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (ConditionPassed())
18229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
18239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
18249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1825e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
18269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!success)
18279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
182853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t target; // target address
18299ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        int32_t imm32; // PC-relative offset
18309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        switch (encoding) {
18319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT1:
18329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
18339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
1834e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
18359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
18369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
18379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT2:
18389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
1839e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
18409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
18419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
18429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT3:
18439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
18449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            {
1845bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
18469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm6 = Bits32(opcode, 21, 16);
1847bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1848bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
18499ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
185053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
18519ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<21>(imm21);
1852e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
18539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
18549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
18559ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            }
18569ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT4:
18579ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            {
1858bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
18599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm10 = Bits32(opcode, 25, 16);
1860bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1861bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
18629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
18639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t I1 = !(J1 ^ S);
18649ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t I2 = !(J2 ^ S);
186553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
18669ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1867e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
18689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
18699ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
18709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            }
18719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingA1:
18729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1873e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
18749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
18759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
18769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        default:
18779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
18789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
18799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!BranchWritePC(context, target))
18809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
18819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
18829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    return true;
18833b620b38cd170c20ea607585021ab2ab50286943Johnny Chen}
18843b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
188553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
188653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
188753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ
188853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool
188953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny ChenEmulateInstructionARM::EmulateCB (ARMEncoding encoding)
189053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{
189153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0
189253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    // ARM pseudo code...
189353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    EncodingSpecificOperations();
189453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if nonzero ^ IsZero(R[n]) then
189553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        BranchWritePC(PC + imm32);
189653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif
189753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
189853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    bool success = false;
189953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
190053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
190153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
190253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
190353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    // Read the register value from the operand register Rn.
1904e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
190553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
190653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
190753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
19089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
19099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1910e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    const uint32_t pc = ReadCoreReg(PC_REG, &success);
191153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
191253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
191353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
191453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    addr_t target;  // target address
191553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    uint32_t imm32; // PC-relative offset to branch forward
191653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    bool nonzero;
191753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    switch (encoding) {
191853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    case eEncodingT1:
1919bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
192053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        nonzero = BitIsSet(opcode, 11);
1921e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        target = pc + imm32;
19229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
192353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        break;
192453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    default:
192553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
192653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    }
192753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (nonzero ^ (reg_val == 0))
192853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        if (!BranchWritePC(context, target))
192953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            return false;
193053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
193153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
193253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen}
193353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
193460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
193560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table.
193660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table.
193760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen//
193860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
193960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table.
194060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table.
194160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH
194260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool
194360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny ChenEmulateInstructionARM::EmulateTB (ARMEncoding encoding)
194460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{
194560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0
194660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // ARM pseudo code...
194760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
194860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if is_tbh then
194960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
195060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    else
195160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        halfwords = UInt(MemU[R[n]+R[m], 1]);
195260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    BranchWritePC(PC + 2*halfwords);
195360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif
195460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
195560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    bool success = false;
195660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
195760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
195860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
195960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
196060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
196160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
196260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    bool is_tbh;     // true if table branch halfword
196360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    switch (encoding) {
196460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    case eEncodingT1:
196560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rn = Bits32(opcode, 19, 16);
196660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rm = Bits32(opcode, 3, 0);
196760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        is_tbh = BitIsSet(opcode, 4);
196860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        if (Rn == 13 || BadReg(Rm))
196960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen            return false;
197060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        if (InITBlock() && !LastInITBlock())
197160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen            return false;
197260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        break;
197360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    default:
197460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
197560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    }
197660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
197760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // Read the address of the table from the operand register Rn.
197860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // The PC can be used, in which case the table immediately follows this instruction.
1979e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t base = ReadCoreReg(Rm, &success);
198060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
198160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
198260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
198360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // the table index
1984e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t index = ReadCoreReg(Rm, &success);
198560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
198660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
198760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
198860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // the offsetted table address
198960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    addr_t addr = base + (is_tbh ? index*2 : index);
199060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
199160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // PC-relative offset to branch forward
199260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    EmulateInstruction::Context context;
199360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.type = EmulateInstruction::eContextTableBranchReadMemory;
1994104c8b69863f229033d616245f56243ca51f1de9Johnny Chen    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
199560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
199660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
199760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
1998e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    const uint32_t pc = ReadCoreReg(PC_REG, &success);
199960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
200060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
200160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
200260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // target address
2003e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    addr_t target = pc + offset;
200460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
200560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
200660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
200760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!BranchWritePC(context, target))
200860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
200960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
201060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    return true;
201160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen}
201260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
20138fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// This instruction adds an immediate value to a register value, and writes the result to the destination
20148fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// register.  It can optionally update the condition flags based on the result.
20158fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chenbool
20168fa2059234b17e9c377eea49b01f0ea084f66843Johnny ChenEmulateInstructionARM::EmulateADDImmARM (ARMEncoding encoding)
20178fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen{
20188fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#if 0
20198fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    // ARM pseudo code...
20208fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    if ConditionPassed() then
20218fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        EncodingSpecificOperations();
20228fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
20238fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        if d == 15 then
20248fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
20258fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        else
20268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            R[d] = result;
20278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            if setflags then
20288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.N = result<31>;
20298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.Z = IsZeroBit(result);
20308fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.C = carry;
20318fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.V = overflow;
20328fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#endif
20338fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
20348fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    bool success = false;
20358fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
20368fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    if (!success)
20378fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        return false;
20388fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
20398fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    if (ConditionPassed())
20408fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    {
20418fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        uint32_t Rd, Rn;
20428fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
20438fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        bool setflags;
20448fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        switch (encoding)
20458fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        {
20468fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        case eEncodingA1:
20478fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rd = Bits32(opcode, 15, 12);
20488fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rn = Bits32(opcode, 19, 16);
20498fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            setflags = BitIsSet(opcode, 20);
20508fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
20518fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            break;
20528fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        default:
20538fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            return false;
20548fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        }
20558fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
20568fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        // Read the first operand.
2057157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
20588fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        if (!success)
20598fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            return false;
20608fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
20618fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
20628fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
20638fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        EmulateInstruction::Context context;
20648fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
20658fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        context.SetNoArgs ();
20668fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
20678fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
20688fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            return false;
20698fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    }
20708fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    return true;
20718fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen}
20728fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
2073d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result
2074d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result.
207526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool
20769f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateADDReg (ARMEncoding encoding)
207726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{
207826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0
207926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    // ARM pseudo code...
208026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if ConditionPassed() then
208126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        EncodingSpecificOperations();
208226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
208326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
208426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if d == 15 then
208526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
208626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        else
208726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            R[d] = result;
208826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            if setflags then
208926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.N = result<31>;
209026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.Z = IsZeroBit(result);
209126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.C = carry;
209226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.V = overflow;
209326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif
209426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
209526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    bool success = false;
209626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
209726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (!success)
209826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        return false;
209926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
210026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (ConditionPassed())
210126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    {
210226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        uint32_t Rd, Rn, Rm;
2103d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        ARM_ShifterType shift_t;
2104d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
2105ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        bool setflags;
210626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        switch (encoding)
210726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        {
2108d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        case eEncodingT1:
2109d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rd = Bits32(opcode, 2, 0);
2110d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rn = Bits32(opcode, 5, 3);
2111d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rm = Bits32(opcode, 8, 6);
2112d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            setflags = !InITBlock();
2113d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_t = SRType_LSL;
2114d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_n = 0;
211526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        case eEncodingT2:
2116bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
211726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            Rm = Bits32(opcode, 6, 3);
2118ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            setflags = false;
2119d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_t = SRType_LSL;
2120d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_n = 0;
212126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            if (Rn == 15 && Rm == 15)
212226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                return false;
2123d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            if (Rd == 15 && InITBlock() && !LastInITBlock())
2124d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                return false;
212526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            break;
21268fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        case eEncodingA1:
21278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rd = Bits32(opcode, 15, 12);
21288fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rn = Bits32(opcode, 19, 16);
21298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rm = Bits32(opcode, 3, 0);
21308fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            setflags = BitIsSet(opcode, 20);
21318fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
21328fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            break;
213326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        default:
213426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
213526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        }
213626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
213726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Read the first operand.
2138157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
213926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (!success)
214026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
214126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
214226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Read the second operand.
2143157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
214426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (!success)
214526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
214626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
2147e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
21488fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
21499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
21509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
21519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
21529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
2153ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
215410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2155ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
215626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    }
215726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    return true;
215826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen}
215926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
216034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (immediate) adds a register value and an immediate value.
216134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
216234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool
216334075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMNImm (ARMEncoding encoding)
216434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{
216534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0
216634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // ARM pseudo code...
216734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if ConditionPassed() then
216834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        EncodingSpecificOperations();
216934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
217034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.N = result<31>;
217134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.Z = IsZeroBit(result);
217234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.C = carry;
217334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.V = overflow;
217434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif
217534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
217634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    bool success = false;
217734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
217834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
217934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
218034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
218134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t Rn; // the first operand
218234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t imm32; // the immediate value to be compared with
218334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    switch (encoding) {
218434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingT1:
218534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 10, 8);
218634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        imm32 = Bits32(opcode, 7, 0);
218734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
218834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
218934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
219034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        break;
219134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    default:
219234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
219334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    }
219434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // Read the register value from the operand register Rn.
219534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
219634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
219734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
219834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
219934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
220034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
220134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    EmulateInstruction::Context context;
220234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
220334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.SetNoArgs ();
220434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
220534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
220634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
220734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    return true;
220834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen}
220934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
221034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (register) adds a register value and an optionally-shifted register value.
221134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
221234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool
221334075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMNReg (ARMEncoding encoding)
221434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{
221534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0
221634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // ARM pseudo code...
221734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if ConditionPassed() then
221834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        EncodingSpecificOperations();
221934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
222034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
222134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.N = result<31>;
222234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.Z = IsZeroBit(result);
222334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.C = carry;
222434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.V = overflow;
222534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif
222634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
222734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    bool success = false;
222834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
222934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
223034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
223134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
223234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t Rn; // the first operand
223334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t Rm; // the second operand
223434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    ARM_ShifterType shift_t;
223534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
223634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    switch (encoding) {
223734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingT1:
223834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 2, 0);
223934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 5, 3);
224034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
224134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
224234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        break;
224334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingT2:
224434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
224534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 6, 3);
224634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
224734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
224834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        if (Rn < 8 && Rm < 8)
224934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen            return false;
225034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        if (Rn == 15 || Rm == 15)
225134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen            return false;
225234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        break;
225334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
225434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
225534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 3, 0);
225634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
225734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    default:
225834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
225934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    }
226034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // Read the register value from register Rn.
226134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
226234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
226334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
226434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
226534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // Read the register value from register Rm.
226634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
226734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
226834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
226934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
227034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
227134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
227234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
227334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    EmulateInstruction::Context context;
227434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
227534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.SetNoArgs();
227634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
227734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
227834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
227934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    return true;
228034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen}
228134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
228234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (immediate) subtracts an immediate value from a register value.
228334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
2284d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool
228534075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMPImm (ARMEncoding encoding)
2286d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{
2287d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0
2288d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    // ARM pseudo code...
2289d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if ConditionPassed() then
2290d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        EncodingSpecificOperations();
2291d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2292d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.N = result<31>;
2293d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.Z = IsZeroBit(result);
2294d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.C = carry;
2295d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.V = overflow;
2296d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif
2297d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2298d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    bool success = false;
2299d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
2300d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if (!success)
2301d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2302d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2303d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t Rn; // the first operand
2304d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t imm32; // the immediate value to be compared with
2305d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    switch (encoding) {
2306d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    case eEncodingT1:
2307d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        Rn = Bits32(opcode, 10, 8);
2308d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        imm32 = Bits32(opcode, 7, 0);
230934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
231034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
231134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2312d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        break;
2313d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    default:
2314d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2315d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    }
2316d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    // Read the register value from the operand register Rn.
2317e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
2318d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if (!success)
2319d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2320d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
232110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
232210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
23239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
23249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextImmediate;
23259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
232610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
232710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        return false;
232810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
2329d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    return true;
2330d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen}
2331d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
233234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (register) subtracts an optionally-shifted register value from a register value.
233334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
2334e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool
233534075cb14fb56cb350e71cc696179ab0f2744423Johnny ChenEmulateInstructionARM::EmulateCMPReg (ARMEncoding encoding)
2336e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{
2337e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0
2338e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // ARM pseudo code...
2339e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if ConditionPassed() then
2340e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        EncodingSpecificOperations();
2341e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2342e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2343e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.N = result<31>;
2344e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.Z = IsZeroBit(result);
2345e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.C = carry;
2346e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.V = overflow;
2347e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif
2348e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2349e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    bool success = false;
2350e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
2351e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2352e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2353e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2354e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t Rn; // the first operand
2355e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t Rm; // the second operand
235634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    ARM_ShifterType shift_t;
235734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
2358e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    switch (encoding) {
2359e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    case eEncodingT1:
2360e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rn = Bits32(opcode, 2, 0);
2361e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rm = Bits32(opcode, 5, 3);
236234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
236334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
2364e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        break;
2365e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    case eEncodingT2:
2366e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2367e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rm = Bits32(opcode, 6, 3);
236834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
236934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
2370e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        if (Rn < 8 && Rm < 8)
2371e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen            return false;
2372e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        if (Rn == 15 || Rm == 15)
2373e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen            return false;
2374e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        break;
237534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
237634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
237734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 3, 0);
237834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
2379e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    default:
2380e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2381e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    }
2382e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // Read the register value from register Rn.
238334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
2384e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2385e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
238634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
2387e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // Read the register value from register Rm.
238834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
2389e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2390e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2391e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
239234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
239334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
239410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
23959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
23969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextImmediate;
23979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs();
239810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
239910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        return false;
240010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
2401e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    return true;
2402e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen}
2403e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
240482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
240582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register.  It can
240682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result.
240782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool
240882f16aa9f19678ffa20b92a8df926e933940d34dJohnny ChenEmulateInstructionARM::EmulateASRImm (ARMEncoding encoding)
240982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{
241082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0
241182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    // ARM pseudo code...
241282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if ConditionPassed() then
241382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        EncodingSpecificOperations();
241482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
241582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
241682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
241782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        else
241882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            R[d] = result;
241982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            if setflags then
242082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.N = result<31>;
242182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.Z = IsZeroBit(result);
242282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.C = carry;
242382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                // APSR.V unchanged
242482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif
242582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
242641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftImm(encoding, SRType_ASR);
242741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
242841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
242941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
243041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register.
243141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update
243241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result.
243341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
243441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateASRReg (ARMEncoding encoding)
243541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
243641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
243741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
243841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
243941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
244041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
244141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
244241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
244341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
244441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
244541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
244641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
244741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
244841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
244941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
245041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftReg(encoding, SRType_ASR);
245141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
245241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
245341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
245441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  It can optionally
245541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result.
245641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
245741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding)
245841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
245941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
246041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
246141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
246241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
246341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
246441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
246541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
246641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        else
246741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            R[d] = result;
246841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            if setflags then
246941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.N = result<31>;
247041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.Z = IsZeroBit(result);
247141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.C = carry;
247241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                // APSR.V unchanged
247341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
247441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
247541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftImm(encoding, SRType_LSL);
247641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
247741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
247841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits,
247941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  The variable number
248041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition
248141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result.
248241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
248341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding)
248441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
248541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
248641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
248741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
248841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
248941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
249041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
249141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
249241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
249341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
249441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
249541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
249641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
249741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
249841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
249941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftReg(encoding, SRType_LSL);
250041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
250141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
250241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
250341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  It can optionally
250441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result.
250541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
250641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding)
250741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
250841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
250941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
251041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
251141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
251241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
251341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
251441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
251541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        else
251641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            R[d] = result;
251741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            if setflags then
251841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.N = result<31>;
251941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.Z = IsZeroBit(result);
252041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.C = carry;
252141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                // APSR.V unchanged
252241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
252341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
252441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftImm(encoding, SRType_LSR);
252541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
252641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
252741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits,
252841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  The variable number
252941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition
253041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result.
253141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
253241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding)
253341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
253441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
253541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
253641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
253741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
253841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
253941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
254041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
254141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
254241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
254341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
254441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
254541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
254641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
254741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
254841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftReg(encoding, SRType_LSR);
254941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
255041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
2551eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2552eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2553eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result.
2554eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
2555eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRORImm (ARMEncoding encoding)
2556eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
2557eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
2558eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
2559eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
2560eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
2561eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2562eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
2563eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
2564eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        else
2565eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            R[d] = result;
2566eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            if setflags then
2567eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.N = result<31>;
2568eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.Z = IsZeroBit(result);
2569eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.C = carry;
2570eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                // APSR.V unchanged
2571eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
2572eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2573eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    return EmulateShiftImm(encoding, SRType_ROR);
2574eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
2575eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2576eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
2577eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2578eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
2579eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result.
2580eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
2581eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRORReg (ARMEncoding encoding)
2582eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
2583eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
2584eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
2585eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
2586eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
2587eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        shift_n = UInt(R[m]<7:0>);
2588eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2589eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        R[d] = result;
2590eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if setflags then
2591eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.N = result<31>;
2592eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.Z = IsZeroBit(result);
2593eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.C = carry;
2594eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // APSR.V unchanged
2595eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
2596eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2597eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    return EmulateShiftReg(encoding, SRType_ROR);
2598eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
2599eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2600eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
2601eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31].
2602eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen//
2603eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result.
2604eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag.
2605eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
2606eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRRX (ARMEncoding encoding)
2607eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
2608eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
2609eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
2610eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
2611eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
2612eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
2613eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
2614eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
2615eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        else
2616eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            R[d] = result;
2617eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            if setflags then
2618eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.N = result<31>;
2619eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.Z = IsZeroBit(result);
2620eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.C = carry;
2621eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                // APSR.V unchanged
2622eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
2623eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2624eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    return EmulateShiftImm(encoding, SRType_RRX);
2625eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
2626eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
262741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
262841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type)
262941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
263041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
263141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
263282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    bool success = false;
263382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
263482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if (!success)
263582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        return false;
263682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
263782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if (ConditionPassed())
263882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    {
2639e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rd;    // the destination register
2640e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rm;    // the first operand register
2641e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t imm5;  // encoding for the shift amount
264282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        uint32_t carry; // the carry bit after the shift operation
264382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        bool setflags;
2644eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2645eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // Special case handling!
2646eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // A8.6.139 ROR (immediate) -- Encoding T1
2647eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if (shift_type == SRType_ROR && encoding == eEncodingT1)
2648eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        {
2649eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
2650eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // have the same decoding of bit fields as the other Thumb2 shift operations.
2651eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            encoding = eEncodingT2;
2652eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        }
2653eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
265482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        switch (encoding) {
265582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingT1:
2656eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // Due to the above special case handling!
2657eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            assert(shift_type != SRType_ROR);
2658eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
265982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 2, 0);
266082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 5, 3);
266182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = !InITBlock();
266282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 10, 6);
266382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
266482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingT2:
2665eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // A8.6.141 RRX
2666eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            assert(shift_type != SRType_RRX);
2667eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
266882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 11, 8);
266982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 3, 0);
267082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = BitIsSet(opcode, 20);
267182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
267282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            if (BadReg(Rd) || BadReg(Rm))
267382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                return false;
267482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
267582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingA1:
267682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 15, 12);
267782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 3, 0);
267882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = BitIsSet(opcode, 20);
267982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 11, 7);
268082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
268182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        default:
268282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            return false;
268382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        }
268482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2685eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // A8.6.139 ROR (immediate)
2686eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if (shift_type == SRType_ROR && imm5 == 0)
2687eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            shift_type = SRType_RRX;
2688eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
268982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // Get the first operand.
2690e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        uint32_t value = ReadCoreReg (Rm, &success);
269182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        if (!success)
269282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            return false;
269382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2694eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // Decode the shift amount if not RRX.
2695eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
269682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2697e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
269882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
269982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
270082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        EmulateInstruction::Context context;
270182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
270282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        context.SetNoArgs ();
270382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
270410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
2705ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
270682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    }
270782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    return true;
270882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen}
270982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2710e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool
271141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type)
2712e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{
271341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
2714e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2715e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    bool success = false;
2716e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
2717e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    if (!success)
2718e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        return false;
2719e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2720e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    if (ConditionPassed())
2721e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    {
2722e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rd;    // the destination register
2723e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rn;    // the first operand register
2724e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
2725e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t carry; // the carry bit after the shift operation
2726e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        bool setflags;
2727e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        switch (encoding) {
2728e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingT1:
2729e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 2, 0);
2730e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Rd;
2731e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 5, 3);
2732e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = !InITBlock();
2733e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
2734e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingT2:
2735e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 11, 8);
2736e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Bits32(opcode, 19, 16);
2737e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 3, 0);
2738e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = BitIsSet(opcode, 20);
2739e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
2740e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen                return false;
2741e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
2742e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingA1:
2743e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 15, 12);
2744e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Bits32(opcode, 3, 0);
2745e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 11, 8);
2746e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = BitIsSet(opcode, 20);
2747e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            if (Rd == 15 || Rn == 15 || Rm == 15)
2748e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen                return false;
2749e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
2750e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        default:
2751e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2752e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        }
2753e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2754e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the first operand.
2755e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        uint32_t value = ReadCoreReg (Rn, &success);
2756e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        if (!success)
2757e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2758e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the Rm register content.
2759e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        uint32_t val = ReadCoreReg (Rm, &success);
2760e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        if (!success)
2761e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2762e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2763e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the shift amount.
2764e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t amt = Bits32(val, 7, 0);
2765e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2766e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
2767e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2768e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
2769e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        EmulateInstruction::Context context;
2770e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
2771e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        context.SetNoArgs ();
2772e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
277310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
2774e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2775e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    }
2776e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    return true;
2777e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen}
2778e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2779b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an
2780713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register.  Optionally the address just above the highest of those locations
2781b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register.
2782b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool
2783b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline TiceEmulateInstructionARM::EmulateLDM (ARMEncoding encoding)
2784b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{
2785b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0
2786b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    // ARM pseudo code...
2787b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if ConditionPassed()
2788b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
2789b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        address = R[n];
2790b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2791b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        for i = 0 to 14
2792b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if registers<i> == '1' then
2793b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                R[i] = MemA[address, 4]; address = address + 4;
2794b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if registers<15> == '1' then
2795b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            LoadWritePC (MemA[address, 4]);
2796b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2797b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
2798b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
2799b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2800b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif
2801b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2802b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    bool success = false;
2803b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
2804b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if (!success)
2805b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        return false;
2806b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2807b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if (ConditionPassed())
2808b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    {
2809b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        uint32_t n;
2810b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        uint32_t registers = 0;
2811b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        bool wback;
2812b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
2813b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        switch (encoding)
2814b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2815b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingT1:
2816b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’);
2817b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 10, 8);
2818b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 7, 0);
2819b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
2820b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsClear (registers, n);
2821b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                // if BitCount(registers) < 1 then UNPREDICTABLE;
2822b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (BitCount(registers) < 1)
2823b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2824b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
2825b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingT2:
2826b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if W == ’1’ && Rn == ’1101’ then SEE POP;
2827b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
2828b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 19, 16);
2829b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 15, 0);
2830b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0xdfff; // Make sure bit 13 is zero.
2831b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsSet (opcode, 21);
2832b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2833b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
2834b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if ((n == 15)
2835b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitCount (registers) < 2)
2836b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
2837b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2838b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2839b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
2840098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
2841b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2842b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2843b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
2844b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (wback
2845b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    && BitIsSet (registers, n))
2846b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2847b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
2848b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2849b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingA1:
2850b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 19, 16);
2851b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 15, 0);
2852b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsSet (opcode, 21);
2853b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if ((n == 15)
2854b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitCount (registers) < 1))
2855b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2856b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
2857b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            default:
2858b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2859b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2860b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2861b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        int32_t offset = 0;
2862b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2863b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (!success)
2864b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            return false;
286585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
28669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
28679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
28689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
28699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
28709bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
2871b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2872b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        for (int i = 0; i < 14; ++i)
2873b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2874b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (BitIsSet (registers, i))
2875b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            {
287685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                context.type = EmulateInstruction::eContextRegisterPlusOffset;
28779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
2878b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (wback && (n == 13)) // Pop Instruction
2879b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2880b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2881b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                // R[i] = MemA [address, 4]; address = address + 4;
2882cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
2883b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (!success)
2884b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2885b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2886b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2887b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2888b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2889b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                offset += addr_byte_size;
2890b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            }
2891b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2892b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2893b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (BitIsSet (registers, 15))
2894b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2895b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            //LoadWritePC (MemA [address, 4]);
289685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            context.type = EmulateInstruction::eContextRegisterPlusOffset;
28979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2898cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
2899b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (!success)
2900b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2901e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
2902668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
2903b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2904b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2905b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2906b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (wback && BitIsClear (registers, n))
2907b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2908fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            // R[n] = R[n] + 4 * BitCount (registers)
2909fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            int32_t offset = addr_byte_size * BitCount (registers);
2910fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
29119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2912b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2913b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
2914b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2915b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2916b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (wback && BitIsSet (registers, n))
2917b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            // R[n] bits(32) UNKNOWN;
2918713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
2919b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    }
2920b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    return true;
2921b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice}
2922713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2923713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers.
2924713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// The consecutive memorty locations end at this address and the address just below the lowest of those locations
2925713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// can optionally be written back tot he base registers.
2926713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool
2927713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding)
2928713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{
2929713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0
2930713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    // ARM pseudo code...
2931713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if ConditionPassed() then
2932713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        EncodingSpecificOperations();
2933713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = R[n] - 4*BitCount(registers) + 4;
2934713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2935713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        for i = 0 to 14
2936713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if registers<i> == ’1then
2937713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  R[i] = MemA[address,4]; address = address + 4;
2938713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2939713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if registers<15> == ’1then
2940713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            LoadWritePC(MemA[address,4]);
2941713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2942713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2943713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
2944713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif
2945713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2946713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    bool success = false;
2947713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
2948713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!success)
2949713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
2950713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2951713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (ConditionPassed())
2952713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    {
2953713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        uint32_t n;
2954713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        uint32_t registers = 0;
2955713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        bool wback;
2956713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
2957713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2958713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // EncodingSpecificOperations();
2959713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        switch (encoding)
2960713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
2961713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            case eEncodingA1:
2962713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
2963713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                n = Bits32 (opcode, 19, 16);
2964713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                registers = Bits32 (opcode, 15, 0);
2965713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                wback = BitIsSet (opcode, 21);
2966b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2967713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
2968713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
2969713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                    return false;
2970713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2971713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                break;
2972713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2973713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            default:
2974713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
2975713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
2976713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // address = R[n] - 4*BitCount(registers) + 4;
2977713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2978713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        int32_t offset = 0;
2979713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2980713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2981713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
2982713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
2983713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2984713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size;
2985713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
29869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
29879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
29889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
29899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
29909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
2991713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2992713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // for i = 0 to 14
2993713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        for (int i = 0; i < 14; ++i)
2994713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
2995713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            // if registers<i> == ’1’ then
2996713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (BitIsSet (registers, i))
2997713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            {
2998713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  // R[i] = MemA[address,4]; address = address + 4;
29999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                  context.SetRegisterPlusOffset (dwarf_reg, offset);
3000cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3001713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  if (!success)
3002713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                      return false;
3003713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3004713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                      return false;
3005713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  offset += addr_byte_size;
3006713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            }
3007713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3008713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3009713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // if registers<15> == ’1’ then
3010713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        //     LoadWritePC(MemA[address,4]);
3011713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (BitIsSet (registers, 15))
3012713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
30139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3014cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3015713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!success)
3016713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
301744c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3018668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
3019713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3020713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3021713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3022713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
3023713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (wback && BitIsClear (registers, n))
3024713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
3025713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3026713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!success)
3027713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3028fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3029fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
3030fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
30319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3032fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr = addr + offset;
3033713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3034713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3035713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3036713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3037713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN;
3038713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (wback && BitIsSet (registers, n))
3039713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
3040713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    }
3041713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    return true;
3042713c2665a27096b68f3f8956222375354f1292f8Caroline Tice}
3043713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3044713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3045713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3046713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register.
30470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool
30480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline TiceEmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding)
30490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{
30500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0
30510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    // ARM pseudo code...
30520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if ConditionPassed() then
30530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
30540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        address = R[n] - 4*BitCount(registers);
30550b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30560b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        for i = 0 to 14
30570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if registers<i> == ’1then
30580b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                  R[i] = MemA[address,4]; address = address + 4;
30590b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if registers<15> == ’1then
30600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                  LoadWritePC(MemA[address,4]);
30610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
30630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
30640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif
30650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    bool success = false;
30670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
30680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if (!success)
30690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        return false;
30700b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30710b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if (ConditionPassed())
30720b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    {
30730b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        uint32_t n;
30740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        uint32_t registers = 0;
30750b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        bool wback;
30760b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
30770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        switch (encoding)
30780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
30790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            case eEncodingT1:
30800b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
30810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                n = Bits32 (opcode, 19, 16);
30820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                registers = Bits32 (opcode, 15, 0);
3083b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
30840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                wback = BitIsSet (opcode, 21);
30850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30860b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
30870b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if ((n == 15)
30880b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    || (BitCount (registers) < 2)
30890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
30900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
30910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3093098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
30940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
30950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
30960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
30970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (wback && BitIsSet (registers, n))
30980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
30990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                break;
31010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            case eEncodingA1:
31030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
31040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                n = Bits32 (opcode, 19, 16);
31050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                registers = Bits32 (opcode, 15, 0);
31060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                wback = BitIsSet (opcode, 21);
31070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31080b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
31090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if ((n == 15) || (BitCount (registers) < 1))
31100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
31110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                break;
31130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            default:
31150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
31160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
31170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3118713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // address = R[n] - 4*BitCount(registers);
3119713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
31200b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        int32_t offset = 0;
3121713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3122713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3123713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
3124713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
3125713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3126713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = address - (addr_byte_size * BitCount (registers));
31279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
31289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
31299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
31309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
31319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
31320b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        for (int i = 0; i < 14; ++i)
31340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
31350b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (BitIsSet (registers, i))
31360b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            {
31370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // R[i] = MemA[address,4]; address = address + 4;
31389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
3139cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
31400b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (!success)
31410b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
31420b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31430b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
31440b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
31450b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31460b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                offset += addr_byte_size;
31470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            }
31480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
31490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        // if registers<15> == ’1’ then
31510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        //     LoadWritePC(MemA[address,4]);
31520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (BitIsSet (registers, 15))
31530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
31549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3155cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
31560b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!success)
31570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
3158e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3159668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
31600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
31610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
31620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
31640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (wback && BitIsClear (registers, n))
31650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
31660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
31670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!success)
31680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
3169fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3170fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
3171fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
31729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3173fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr = addr + offset;
31740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
31750b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
31760b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
31770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
31780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
31790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (wback && BitIsSet (registers, n))
3180713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
31810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    }
31820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    return true;
31830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice}
318485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3185713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3186713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3187713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register.
318885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool
318985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline TiceEmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding)
319085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{
319185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0
319285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if ConditionPassed() then
319385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        EncodingSpecificOperations();
319485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        address = R[n] + 4;
319585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
319685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        for i = 0 to 14
319785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if registers<i> == ’1then
319885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                  R[i] = MemA[address,4]; address = address + 4;
319985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if registers<15> == ’1then
320085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            LoadWritePC(MemA[address,4]);
320185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
320285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
320385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
320485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif
320585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
320685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    bool success = false;
320785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
320885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if (!success)
320985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        return false;
321085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
321185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if (ConditionPassed())
321285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    {
321385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        uint32_t n;
321485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        uint32_t registers = 0;
321585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        bool wback;
321685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
321785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        switch (encoding)
321885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
321985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            case eEncodingA1:
322085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
322185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                n = Bits32 (opcode, 19, 16);
322285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                registers = Bits32 (opcode, 15, 0);
322385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                wback = BitIsSet (opcode, 21);
322485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
322585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
322685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if ((n == 15) || (BitCount (registers) < 1))
322785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
322885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
322985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                break;
323085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            default:
323185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
323285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
323385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // address = R[n] + 4;
323485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
323585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        int32_t offset = 0;
3236713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3237713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3238713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
3239713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
3240713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3241713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = address + addr_byte_size;
324285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
32439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
32449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
32459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
32469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
32479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
324885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
324985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        for (int i = 0; i < 14; ++i)
325085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
325185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (BitIsSet (registers, i))
325285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            {
325385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // R[i] = MemA[address,4]; address = address + 4;
325485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
32559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
3256cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
325785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if (!success)
325885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
325985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
326085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
326185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
326285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
326385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                offset += addr_byte_size;
326485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            }
326585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
326685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
326785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // if registers<15> == ’1’ then
326885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        //     LoadWritePC(MemA[address,4]);
326985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (BitIsSet (registers, 15))
327085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
32719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3272cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
327385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!success)
327485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
3275e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3276668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
327785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
327885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
327985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
328085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
328185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (wback && BitIsClear (registers, n))
328285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
328385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
328485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!success)
328585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
3286fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3287fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = addr_byte_size * BitCount (registers);
3288fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
32899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3290fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr = addr + offset;
329185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
329285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
329385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
329485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
329585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
329685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (wback && BitIsSet (registers, n))
3297713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
329885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    }
329985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    return true;
330085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice}
33010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3302ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and
3303ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register.
3304ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb)
3305ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool
3306ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
3307ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{
3308ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0
3309ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    // ARM pseudo code...
3310ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (ConditionPassed())
3311ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    {
3312ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3313ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3314ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        address = if index then offset_addr else R[n];
3315ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        data = MemU[address,4];
3316ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if wback then R[n] = offset_addr;
3317ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if t == 15 then
3318ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3319ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        elsif UnalignedSupport() || address<1:0> = '00' then
3320ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            R[t] = data;
3321ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3322ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    }
3323ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif
3324ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3325ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    bool success = false;
3326ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
3327ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (!success)
3328ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        return false;
3329ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3330ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (ConditionPassed())
3331ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    {
3332ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t Rt; // the destination register
3333ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t Rn; // the base register
3334ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t imm32; // the immediate offset used to form the address
3335ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        addr_t offset_addr; // the offset address
3336ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        addr_t address; // the calculated address
3337ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t data; // the literal data value from memory load
3338ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        bool add, index, wback;
3339ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        switch (encoding) {
3340ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        case eEncodingT1:
3341ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            Rt = Bits32(opcode, 5, 3);
3342ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            Rn = Bits32(opcode, 2, 0);
3343ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3344ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            // index = TRUE; add = TRUE; wback = FALSE
3345ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            add = true;
3346ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            index = true;
3347ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            wback = false;
3348ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            break;
3349ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        default:
3350ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3351ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3352ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
3353ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (!success)
3354ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3355ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (add)
3356ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            offset_addr = base + imm32;
3357ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else
3358ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            offset_addr = base - imm32;
3359ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3360ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        address = (index ? offset_addr : base);
3361ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3362ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (wback)
3363ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
33649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            EmulateInstruction::Context ctx;
33659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            ctx.type = EmulateInstruction::eContextRegisterPlusOffset;
33669bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Register dwarf_reg;
33679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
33689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base));
33699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
3370ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3371ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3372ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3373ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3374ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        // Prepare to write to the Rt register.
33759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
33769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
33779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
3378ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3379ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        // Read memory from the address.
3380cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        data = MemURead(context, address, 4, 0, &success);
3381ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (!success)
3382ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3383ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3384ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (Rt == 15)
3385ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
3386ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (Bits32(address, 1, 0) == 0)
3387ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            {
3388668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen                if (!LoadWritePC(context, data))
3389ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                    return false;
3390ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            }
3391ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            else
3392ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3393ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3394ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3395ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
3396ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3397ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3398ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3399ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else
3400ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3401ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    }
3402ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    return true;
3403ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen}
3404ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3405af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3406af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3407af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
3408fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool
3409fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::EmulateSTM (ARMEncoding encoding)
3410fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{
3411fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0
3412fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if ConditionPassed() then
3413fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3414fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        address = R[n];
3415fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3416fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        for i = 0 to 14
3417fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if registers<i> == ’1then
3418fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
3419fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3420fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                else
3421fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    MemA[address,4] = R[i];
3422fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                address = address + 4;
3423fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3424fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if registers<15> == ’1then // Only possible for encoding A1
3425fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            MemA[address,4] = PCStoreValue();
3426fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if wback then R[n] = R[n] + 4*BitCount(registers);
3427fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif
3428fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3429fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    bool success = false;
3430fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
3431fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if (!success)
3432fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        return false;
3433fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3434fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if (ConditionPassed ())
3435fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    {
3436fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        uint32_t n;
3437fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        uint32_t registers = 0;
3438fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        bool wback;
3439fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3440fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3441fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3442fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        switch (encoding)
3443fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
3444fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingT1:
3445fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE;
3446fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 10, 8);
3447fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 7, 0);
3448b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3449fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = true;
3450fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3451fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if BitCount(registers) < 1 then UNPREDICTABLE;
3452fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if (BitCount (registers) < 1)
3453fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3454fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3455fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
3456fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3457fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingT2:
3458fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’);
3459fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 19, 16);
3460fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 15, 0);
3461b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3462fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = BitIsSet (opcode, 21);
3463fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3464fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3465fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if ((n == 15) || (BitCount (registers) < 2))
3466fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3467fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3468fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
3469fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if (wback && BitIsSet (registers, n))
3470fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3471fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3472fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
3473fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3474fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingA1:
3475fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3476fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 19, 16);
3477fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 15, 0);
3478fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = BitIsSet (opcode, 21);
3479fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3480fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3481fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
3482fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3483fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3484fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
3485fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3486fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            default:
3487fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3488fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3489fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3490fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // address = R[n];
3491fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        int32_t offset = 0;
3492fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3493fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (!success)
3494fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            return false;
3495fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
34969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
34979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
34989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register base_reg;
34999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3500fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3501fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // for i = 0 to 14
3502fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        for (int i = 0; i < 14; ++i)
3503fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
3504fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            int lowest_set_bit = 14;
3505fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            // if registers<i> == ’1’ then
3506fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (BitIsSet (registers, i))
3507fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            {
3508fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  if (i < lowest_set_bit)
3509fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      lowest_set_bit = i;
3510fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  // if i == n && wback && i != LowestSetBit(registers) then
3511fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  if ((i == n) && wback && (i != lowest_set_bit))
3512fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3513fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      WriteBits32UnknownToMemory (address + offset);
3514fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  else
3515fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  {
3516fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                     // MemA[address,4] = R[i];
3517fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3518fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      if (!success)
3519fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                          return false;
3520fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
35219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      Register data_reg;
35229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
35239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3524cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
3525fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                          return false;
3526fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  }
3527fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3528fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  // address = address + 4;
3529fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  offset += addr_byte_size;
3530fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            }
3531fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3532fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3533fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // if registers<15> == ’1’ then // Only possible for encoding A1
3534fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //     MemA[address,4] = PCStoreValue();
3535fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (BitIsSet (registers, 15))
3536fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
35379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Register pc_reg;
35389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
35399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
3540fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3541fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (!success)
3542fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3543fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3544cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3545fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3546fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3547fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3548fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // if wback then R[n] = R[n] + 4*BitCount(registers);
3549fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (wback)
3550fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
3551fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = addr_byte_size * BitCount (registers);
3552fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
35539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3554fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr_t data = address + offset;
3555fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3556fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3557fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3558fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    }
3559fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    return true;
3560fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice}
3561fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3562af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
3563af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
3564af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
35651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool
35661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline TiceEmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding)
35671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{
35681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0
35691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if ConditionPassed() then
35701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        EncodingSpecificOperations();
35711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        address = R[n] - 4*BitCount(registers) + 4;
35721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
35731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        for i = 0 to 14
35741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if registers<i> == ’1then
35751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
35761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN;
35771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                else
35781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    MemA[address,4] = R[i];
35791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                address = address + 4;
35801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
35811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if registers<15> == ’1then
35821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            MemA[address,4] = PCStoreValue();
35831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
35841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if wback then R[n] = R[n] - 4*BitCount(registers);
35851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif
35861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
35871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    bool success = false;
35881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
35891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if (!success)
35901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        return false;
35911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
35921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if (ConditionPassed ())
35931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    {
35941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        uint32_t n;
35951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        uint32_t registers = 0;
35961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        bool wback;
35971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
35981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
35991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // EncodingSpecificOperations();
36001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        switch (encoding)
36011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
36021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            case eEncodingA1:
36031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
36041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                n = Bits32 (opcode, 19, 16);
36051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                registers = Bits32 (opcode, 15, 0);
36061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                wback = BitIsSet (opcode, 21);
36071511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
36091511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
36101511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    return false;
36111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                break;
36121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            default:
36131511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
36141511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
36151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // address = R[n] - 4*BitCount(registers) + 4;
36171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        int32_t offset = 0;
36181511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
36191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (!success)
36201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            return false;
36211511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36221511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        address = address - (addr_byte_size * BitCount (registers)) + 4;
36231511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36241511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        EmulateInstruction::Context context;
36251511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
36261511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        Register base_reg;
36271511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
36281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36291511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // for i = 0 to 14
36301511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        for (int i = 0; i < 14; ++i)
36311511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
36321511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            int lowest_bit_set = 14;
36331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            // if registers<i> == ’1’ then
36341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (BitIsSet (registers, i))
36351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            {
36361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if (i < lowest_bit_set)
36371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    lowest_bit_set = i;
36381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                //if i == n && wback && i != LowestSetBit(registers) then
36391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if ((i == n) && wback && (i != lowest_bit_set))
36401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    // MemA[address,4] = bits(32) UNKNOWN;
36411511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    WriteBits32UnknownToMemory (address + offset);
36421511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                else
36431511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                {
36441511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    // MemA[address,4] = R[i];
36451511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
36461511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    if (!success)
36471511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                        return false;
36481511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    Register data_reg;
36501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
36511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3652cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
36531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                        return false;
36541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                }
36551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // address = address + 4;
36571511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                offset += addr_byte_size;
36581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            }
36591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
36601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // if registers<15> == ’1’ then
36621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        //    MemA[address,4] = PCStoreValue();
36631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (BitIsSet (registers, 15))
36641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
36651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            Register pc_reg;
36661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
36671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
36681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
36691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (!success)
36701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
36711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
3672cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
36731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
36741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
36751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
36761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // if wback then R[n] = R[n] - 4*BitCount(registers);
36771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (wback)
36781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
3679af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
36801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
36811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.SetImmediateSigned (offset);
36821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            addr_t data = address + offset;
36831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
36841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
36851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
36861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    }
36871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    return true;
36881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice}
36891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
3690af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
3691af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
3692af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register.
3693b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool
3694b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline TiceEmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding)
3695b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{
3696b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0
3697b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if ConditionPassed() then
3698b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3699b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        address = R[n] - 4*BitCount(registers);
3700b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3701b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        for i = 0 to 14
3702b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if registers<i> == ’1then
3703b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
3704b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
3705b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                else
3706b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    MemA[address,4] = R[i];
3707b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                address = address + 4;
3708b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3709b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if registers<15> == ’1then // Only possible for encoding A1
3710b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            MemA[address,4] = PCStoreValue();
3711b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3712b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if wback then R[n] = R[n] - 4*BitCount(registers);
3713b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif
3714b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3715b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3716b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    bool success = false;
3717b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
3718b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if (!success)
3719b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        return false;
3720b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3721b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if (ConditionPassed ())
3722b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    {
3723b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        uint32_t n;
3724b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        uint32_t registers = 0;
3725b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        bool wback;
3726b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3727b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3728b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3729b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        switch (encoding)
3730b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3731b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            case eEncodingT1:
3732b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if W == ’1’ && Rn == ’1101’ then SEE PUSH;
3733b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
3734b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
3735b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // See PUSH
3736b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
3737b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’);
3738b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                n = Bits32 (opcode, 19, 16);
3739b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = Bits32 (opcode, 15, 0);
3740b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
3741b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                wback = BitIsSet (opcode, 21);
3742b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3743b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((n == 15) || BitCount (registers) < 2)
3744b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
3745b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
3746b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (wback && BitIsSet (registers, n))
3747b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
3748b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                break;
3749b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3750b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            case eEncodingA1:
3751b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH;
3752b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
3753b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
3754b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // See Push
3755b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
3756b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3757b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                n = Bits32 (opcode, 19, 16);
3758b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = Bits32 (opcode, 15, 0);
3759b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                wback = BitIsSet (opcode, 21);
3760b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3761b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((n == 15) || BitCount (registers) < 1)
3762b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
3763b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                break;
3764b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3765b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            default:
3766b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3767b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3768b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3769b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // address = R[n] - 4*BitCount(registers);
3770b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3771b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        int32_t offset = 0;
3772b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3773b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (!success)
3774b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        return false;
3775b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3776b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        address = address - (addr_byte_size * BitCount (registers));
3777b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3778b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        EmulateInstruction::Context context;
3779b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
3780b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        Register base_reg;
3781b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3782b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3783b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // for i = 0 to 14
3784b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        for (int i = 0; i < 14; ++i)
3785b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3786b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            uint32_t lowest_set_bit = 14;
3787b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            // if registers<i> == ’1’ then
3788b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (BitIsSet (registers, i))
3789b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            {
3790b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (i < lowest_set_bit)
3791b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    lowest_set_bit = i;
3792b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if i == n && wback && i != LowestSetBit(registers) then
3793b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((i == n) && wback && (i != lowest_set_bit))
3794b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
3795b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    WriteBits32UnknownToMemory (address + offset);
3796b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                else
3797b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
3798b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // MemA[address,4] = R[i];
3799b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3800b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    if (!success)
3801b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                        return false;
3802b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3803b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    Register data_reg;
3804b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3805b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3806cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3807b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                        return false;
3808b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
3809b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3810b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // address = address + 4;
3811b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                offset += addr_byte_size;
3812b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            }
3813b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3814b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3815b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // if registers<15> == ’1’ then // Only possible for encoding A1
3816b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        //     MemA[address,4] = PCStoreValue();
3817b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (BitIsSet (registers, 15))
3818b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3819b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            Register pc_reg;
3820b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3821b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
3822b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3823b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (!success)
3824b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3825b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3826cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3827b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3828b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3829b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3830b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // if wback then R[n] = R[n] - 4*BitCount(registers);
3831b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (wback)
3832b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3833af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
3834af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3835af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.SetImmediateSigned (offset);
3836af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            addr_t data = address + offset;
3837af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3838af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
3839af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3840af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    }
3841af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    return true;
3842af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice}
3843af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3844af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
3845af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations start just above this address, and the address of the last
3846af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
3847af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool
3848af556564f80fd417a9158754f5e2ee692e183f6dCaroline TiceEmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding)
3849af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{
3850af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0
3851af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if ConditionPassed() then
3852af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        EncodingSpecificOperations();
3853af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        address = R[n] + 4;
3854af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3855af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        for i = 0 to 14
3856af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if registers<i> == ’1then
3857af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if i == n && wback && i != LowestSetBit(registers) then
3858af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    MemA[address,4] = bits(32) UNKNOWN;
3859af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                else
3860af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    MemA[address,4] = R[i];
3861af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                address = address + 4;
3862af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3863af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if registers<15> == ’1then
3864af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            MemA[address,4] = PCStoreValue();
3865af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3866af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if wback then R[n] = R[n] + 4*BitCount(registers);
3867af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif
3868af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3869af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    bool success = false;
3870af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
3871af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if (!success)
3872af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        return false;
3873af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3874af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if (ConditionPassed())
3875af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    {
3876af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t n;
3877af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t registers = 0;
3878af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        bool wback;
3879af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3880af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3881af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // EncodingSpecificOperations();
3882af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        switch (encoding)
3883af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3884af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            case eEncodingA1:
3885af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3886af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                n = Bits32 (opcode, 19, 16);
3887af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                registers = Bits32 (opcode, 15, 0);
3888af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                wback = BitIsSet (opcode, 21);
3889af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3890af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3891af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if ((n == 15) && (BitCount (registers) < 1))
3892af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    return false;
3893af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                break;
3894af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            default:
3895af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
3896af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3897af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // address = R[n] + 4;
3898af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3899af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        int32_t offset = 0;
3900af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3901af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (!success)
3902af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            return false;
3903af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3904af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        address = address + addr_byte_size;
3905af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3906af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        EmulateInstruction::Context context;
3907af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
3908af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        Register base_reg;
3909af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3910af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3911af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t lowest_set_bit = 14;
3912af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // for i = 0 to 14
3913af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        for (int i = 0; i < 14; ++i)
3914af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3915af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            // if registers<i> == ’1’ then
3916af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (BitIsSet (registers, i))
3917af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            {
3918af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if (i < lowest_set_bit)
3919af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    lowest_set_bit = i;
3920af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // if i == n && wback && i != LowestSetBit(registers) then
3921af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if ((i == n) && wback && (i != lowest_set_bit))
3922af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    // MemA[address,4] = bits(32) UNKNOWN;
3923af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    WriteBits32UnknownToMemory (address + offset);
3924af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // else
3925af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                else
3926af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                {
3927af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    // MemA[address,4] = R[i];
3928af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3929af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    if (!success)
3930af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                        return false;
3931af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3932af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    Register data_reg;
3933af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3934af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3935cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3936af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                        return false;
3937af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                }
3938af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3939af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // address = address + 4;
3940af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                offset += addr_byte_size;
3941af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            }
3942af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3943af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3944af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // if registers<15> == ’1’ then
3945af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            // MemA[address,4] = PCStoreValue();
3946af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (BitIsSet (registers, 15))
3947af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3948af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            Register pc_reg;
3949af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3950af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
3951af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3952af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (!success)
3953af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            return false;
3954af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3955cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3956af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
3957af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3958af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3959af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // if wback then R[n] = R[n] + 4*BitCount(registers);
3960af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (wback)
3961af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3962b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            offset = addr_byte_size * BitCount (registers);
3963b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3964b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.SetImmediateSigned (offset);
3965b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            addr_t data = address + offset;
3966b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3967b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3968b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3969b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    }
3970b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    return true;
3971b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice}
39727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
39737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
39747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
39757fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool
39767fac857ec72051dc0a91b027719c275ea672a470Caroline TiceEmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding)
39777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{
39787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0
39797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if ConditionPassed() then
39807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
39817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
39827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        address = if index then offset_addr else R[n];
39837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if UnalignedSupport() || address<1:0> == ’00’ then
39847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            MemU[address,4] = R[t];
39857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else // Can only occur before ARMv7
39867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            MemU[address,4] = bits(32) UNKNOWN;
39877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if wback then R[n] = offset_addr;
39887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif
39897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
39907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    bool success = false;
39917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
39927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if (!success)
39937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        return false;
39947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
39957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if (ConditionPassed())
39967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    {
39977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
39987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
39997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t t;
40007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t n;
40017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t imm32;
40027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool index;
40037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool add;
40047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool wback;
40057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
40067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        switch (encoding)
40077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
40087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT1:
40097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32);
40107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 2, 0);
40117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 5, 3);
40127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 10, 6) << 2;
40137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
40157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
40167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = false;
40177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
40187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
40197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT2:
40217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32);
40227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 10, 8);
40237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = 13;
40247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
40257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
40277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
40287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = true;
40297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
40307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
40317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT3:
40337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if Rn == ’1111’ then UNDEFINED;
40347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
40357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
40367fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40377fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
40387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 15, 12);
40397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 19, 16);
40407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
40417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
40437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
40447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = true;
40457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
40467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if t == 15 then UNPREDICTABLE;
40487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if (t == 15)
40497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
40507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
40517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40527fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT4:
40537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT;
40547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH;
40557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED;
40567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if ((Bits32 (opcode, 19, 16) == 15)
40577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
40587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
40597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
40617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 15, 12);
40627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 19, 16);
40637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
40647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
40667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = BitIsSet (opcode, 10);
40677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = BitIsSet (opcode, 9);
40687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = BitIsSet (opcode, 8);
40697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
40717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if ((t == 15) || (wback && (n == t)))
40727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
40737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
40747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            default:
40767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
40777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
40787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        addr_t offset_addr;
40807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        addr_t address;
4081b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
40827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
40837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
40847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (!success)
40857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            return false;
40867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (add)
40887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            offset_addr = base_address + imm32;
40897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
40907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            offset_addr = base_address - imm32;
40917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // address = if index then offset_addr else R[n];
40937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (index)
40947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            address = offset_addr;
40957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
40967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            address = base_address;
40977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
40987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        EmulateInstruction::Context context;
40997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        context.type = eContextRegisterStore;
41007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        Register base_reg;
41017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
41027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
41037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // if UnalignedSupport() || address<1:0> == ’00’ then
41047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
41057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
41067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            // MemU[address,4] = R[t];
41077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
41087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            if (!success)
41097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
41107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
41117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            Register data_reg;
41127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
41137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            int32_t offset = address - base_address;
41147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4115cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, address, data, addr_byte_size))
41167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
41177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
41187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
41197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
41207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            // MemU[address,4] = bits(32) UNKNOWN;
41217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            WriteBits32UnknownToMemory (address);
41227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
41237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
41247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // if wback then R[n] = offset_addr;
41257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (wback)
41267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
41277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.type = eContextRegisterLoad;
41287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.SetAddress (offset_addr);
41297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
41307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
41317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
41327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    }
41337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    return true;
41347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice}
4135af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
41363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
41373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory.   The offset register value can optionally be shifted.
41383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool
41393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline TiceEmulateInstructionARM::EmulateSTRRegister (ARMEncoding encoding)
41403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{
41413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0
41423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if ConditionPassed() then
41433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
41443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
41453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
41463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        address = if index then offset_addr else R[n];
41473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if t == 15 then // Only possible for encoding A1
41483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = PCStoreValue();
41493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
41503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = R[t];
41513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then
41523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            MemU[address,4] = data;
41533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else // Can only occur before ARMv7
41543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            MemU[address,4] = bits(32) UNKNOWN;
41553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if wback then R[n] = offset_addr;
41563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif
41573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    bool success = false;
41593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
41603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if (!success)
41613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        return false;
41623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if (ConditionPassed())
41643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    {
41653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
41663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t t;
41683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t n;
41693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t m;
41703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        ARM_ShifterType shift_t;
41713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t shift_n;
41723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool index;
41733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool add;
41743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool wback;
41753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
41773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        switch (encoding)
41783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
41793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingT1:
41803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
41813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
41823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 2, 0);
41833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 5, 3);
41843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 8, 6);
41853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
41873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = true;
41883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = true;
41893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = false;
41903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
41923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_t = SRType_LSL;
41933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = 0;
41943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
41953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingT2:
41973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if Rn == ’1111’ then UNDEFINED;
41983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (Bits32 (opcode, 19, 16) == 15)
41993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
42003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
42023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 15, 12);
42033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 19, 16);
42043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 3, 0);
42053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
42073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = true;
42083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = true;
42093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = false;
42103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
42123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_t = SRType_LSL;
42133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
42143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if t == 15 || BadReg(m) then UNPREDICTABLE;
42163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if ((t == 15) || (BadReg (m)))
42173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
42183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
42193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingA1:
42213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            {
42223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if P == ’0’ && W == ’1’ then SEE STRT;
42233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
42243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 15, 12);
42253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 19, 16);
42263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 3, 0);
42273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
42293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = BitIsSet (opcode, 24);
42303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = BitIsSet (opcode, 23);
42313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
42323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
42343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                uint32_t typ = Bits32 (opcode, 6, 5);
42353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
42363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = DecodeImmShift(typ, imm5, shift_t);
42373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if m == 15 then UNPREDICTABLE;
42393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (m == 15)
42403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
42413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
42433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (wback && ((n == 15) || (n == t)))
42443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
42453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
42473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            }
42483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            default:
42493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
42503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
42513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t offset_addr;
42533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t address;
42543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        int32_t offset = 0;
42553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
42573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
42583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
42593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
42613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
42623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
42633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4265e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        offset = Shift (Rm_data, shift_t, shift_n, APSR_C);
42663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
42683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (add)
42693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            offset_addr = base_address + offset;
42703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
42713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            offset_addr = base_address - offset;
42723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // address = if index then offset_addr else R[n];
42743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (index)
42753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            address = offset_addr;
42763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
42773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            address = base_address;
42783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t data;
42803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if t == 15 then // Only possible for encoding A1
42813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (t == 15)
42823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // data = PCStoreValue();
42833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
42843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
42853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // data = R[t];
42863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
42873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
42893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
42903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        EmulateInstruction::Context context;
42923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        context.type = eContextRegisterStore;
42933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
42943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then
42953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (UnalignedSupport ()
42963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            || (BitIsClear (address, 1) && BitIsClear (address, 0))
42973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            || CurrentInstrSet() == eModeARM)
42983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
42993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // MemU[address,4] = data;
43003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
43013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            Register base_reg;
43023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
43033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
43043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            Register data_reg;
43053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
43063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
43073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4308cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, address, data, addr_byte_size))
43093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
43103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
43113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
43123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
43133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // MemU[address,4] = bits(32) UNKNOWN;
43143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            WriteBits32UnknownToMemory (address);
43153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
43163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if wback then R[n] = offset_addr;
43173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (wback)
43183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
43193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.type = eContextRegisterLoad;
43203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.SetAddress (offset_addr);
43213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
43223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
43233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
43243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
43253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    }
43263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    return true;
43273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice}
432873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
432973a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool
433073a29de4b8f59594fd7a559c05fa795afe754551Caroline TiceEmulateInstructionARM::EmulateSTRBThumb (ARMEncoding encoding)
433173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{
433273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0
433373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if ConditionPassed() then
433473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
433573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
433673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        address = if index then offset_addr else R[n];
433773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        MemU[address,1] = R[t]<7:0>;
433873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if wback then R[n] = offset_addr;
433973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif
434073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
434173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
434273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    bool success = false;
434373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
434473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if (!success)
434573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        return false;
434673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
434773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if (ConditionPassed ())
434873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    {
434973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t t;
435073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t n;
435173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t imm32;
435273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool index;
435373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool add;
435473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool wback;
435573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
435673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        switch (encoding)
435773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        {
435873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT1:
435973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
436073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 2, 0);
436173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 5, 3);
436273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 10, 6);
436373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
436473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
436573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = true;
436673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = true;
436773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = false;
436873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
436973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
437073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT2:
437173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if Rn == ’1111’ then UNDEFINED;
437273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
437373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
437473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
437573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
437673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 15, 12);
437773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 19, 16);
437873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
437973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
438073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
438173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = true;
438273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = true;
438373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = false;
438473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
438573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if BadReg(t) then UNPREDICTABLE;
438673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (BadReg (t))
438773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
438873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
438973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
439073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT3:
439173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRBT;
439273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED;
439373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
439473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
439573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
439673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
439773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 15, 12);
439873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 19, 16);
439973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
440073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
440173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
440273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = BitIsSet (opcode, 10);
440373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = BitIsSet (opcode, 9);
440473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = BitIsSet (opcode, 8);
440573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
440673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
440773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if ((BadReg (t)) || (wback && (n == t)))
440873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
440973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
441073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
441173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            default:
441273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                return false;
441373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        }
441473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
441573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t offset_addr;
441673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t address;
441773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
441873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (!success)
441973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
442073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
442173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
442273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (add)
442373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            offset_addr = base_address + imm32;
442473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        else
442573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            offset_addr = base_address - imm32;
442673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
442773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // address = if index then offset_addr else R[n];
442873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (index)
442973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            address = offset_addr;
443073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        else
443173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            address = base_address;
443273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
4433cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        // MemU[address,1] = R[t]<7:0>
443473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        Register base_reg;
443573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
443673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
443773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        Register data_reg;
443873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
443973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
444073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        EmulateInstruction::Context context;
444173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        context.type = eContextRegisterStore;
444273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
444373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
444473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
444573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (!success)
444673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
444773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
444873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        data = Bits32 (data, 7, 0);
444973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
4450cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        if (!MemUWrite (context, address, data, 1))
445173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
445273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
445373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // if wback then R[n] = offset_addr;
445473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (wback)
445573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        {
445673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            context.type = eContextRegisterLoad;
445773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            context.SetAddress (offset_addr);
445873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
445973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                return false;
446073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        }
446173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
446273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    }
446373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
446473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    return true;
446573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice}
44663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
4467157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
4468157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// and writes the result to the destination register.  It can optionally update the condition flags
4469157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// based on the result.
4470157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool
4471157b959b101cbdddb81a690d00ff0697540d83e7Johnny ChenEmulateInstructionARM::EmulateADCImm (ARMEncoding encoding)
4472157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{
4473157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0
4474157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    // ARM pseudo code...
4475157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if ConditionPassed() then
4476157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EncodingSpecificOperations();
4477157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
4478157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
4479157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
4480157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        else
4481157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            R[d] = result;
4482157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if setflags then
4483157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.N = result<31>;
4484157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.Z = IsZeroBit(result);
4485157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.C = carry;
4486157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.V = overflow;
4487157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif
4488157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4489157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    bool success = false;
4490157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
4491157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if (!success)
4492157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        return false;
4493157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4494157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if (ConditionPassed())
4495157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    {
4496157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t Rd, Rn;
4497157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
4498157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        bool setflags;
4499157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        switch (encoding)
4500157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        {
4501157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingT1:
4502157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 11, 8);
4503157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
4504157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
4505157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
4506157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (BadReg(Rd) || BadReg(Rn))
4507157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                return false;
4508157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
4509157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingA1:
4510157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 15, 12);
4511157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
4512157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
4513157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
4514157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
4515157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (Rd == 15 && setflags)
4516157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                return false;
4517157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
4518157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        default:
4519157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4520157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        }
4521157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4522157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // Read the first operand.
4523157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        int32_t val1 = ReadCoreReg(Rn, &success);
4524157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!success)
4525157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4526157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4527157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
4528157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4529157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EmulateInstruction::Context context;
4530157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
4531157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.SetNoArgs ();
4532157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4533157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
4534157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4535157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    }
4536157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    return true;
4537157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen}
4538157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4539157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
4540157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// register value, and writes the result to the destination register.  It can optionally update the
4541157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// condition flags based on the result.
4542157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool
4543157b959b101cbdddb81a690d00ff0697540d83e7Johnny ChenEmulateInstructionARM::EmulateADCReg (ARMEncoding encoding)
4544157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{
4545157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0
4546157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    // ARM pseudo code...
4547157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if ConditionPassed() then
4548157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EncodingSpecificOperations();
4549157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
4550157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
4551157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
4552157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
4553157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        else
4554157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            R[d] = result;
4555157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if setflags then
4556157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.N = result<31>;
4557157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.Z = IsZeroBit(result);
4558157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.C = carry;
4559157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.V = overflow;
4560157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif
4561157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4562157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    bool success = false;
4563157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
4564157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if (!success)
4565157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        return false;
4566157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4567157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if (ConditionPassed())
4568157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    {
4569157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t Rd, Rn, Rm;
4570157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        ARM_ShifterType shift_t;
4571157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
4572157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        bool setflags;
4573157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        switch (encoding)
4574157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        {
4575157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingT1:
4576157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
4577157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rm = Bits32(opcode, 5, 3);
4578157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = !InITBlock();
4579157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_t = SRType_LSL;
4580157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_n = 0;
4581157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingT2:
4582157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 11, 8);
4583157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
4584157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rm = Bits32(opcode, 3, 0);
4585157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
4586157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
4587157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
4588157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                return false;
4589157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
4590157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingA1:
4591157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 15, 12);
4592157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
4593157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rm = Bits32(opcode, 3, 0);
4594157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
4595157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
4596157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
4597157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (Rd == 15 && setflags)
4598157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                return false;
4599157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
4600157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        default:
4601157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4602157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        }
4603157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4604157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // Read the first operand.
4605157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        int32_t val1 = ReadCoreReg(Rn, &success);
4606157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!success)
4607157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4608157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4609157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // Read the second operand.
4610157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        int32_t val2 = ReadCoreReg(Rm, &success);
4611157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!success)
4612157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4613157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4614157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
4615157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
4616157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4617157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EmulateInstruction::Context context;
4618157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
4619157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.SetNoArgs ();
4620157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4621157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
4622157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
4623157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    }
4624157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    return true;
4625157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen}
4626157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
4627e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
4628e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// to the destination register.  It can optionally update the condition flags based on the result.
4629e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool
4630e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny ChenEmulateInstructionARM::EmulateANDImm (ARMEncoding encoding)
4631e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{
4632e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0
4633e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    // ARM pseudo code...
4634e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if ConditionPassed() then
4635e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EncodingSpecificOperations();
4636e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        result = R[n] AND imm32;
4637e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
4638e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
4639e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        else
4640e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            R[d] = result;
4641e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if setflags then
4642e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.N = result<31>;
4643e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.Z = IsZeroBit(result);
4644e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.C = carry;
4645e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                // APSR.V unchanged
4646e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif
4647e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4648e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    bool success = false;
4649e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
4650e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if (!success)
4651e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        return false;
4652e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4653e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if (ConditionPassed())
4654e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    {
4655e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t Rd, Rn;
4656e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
4657e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        bool setflags;
4658e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
4659e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        switch (encoding)
4660e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        {
4661e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingT1:
4662e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 11, 8);
4663e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
4664e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
4665e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
4666de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            // if Rd == '1111' && S == '1' then SEE TST (immediate);
4667e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
4668de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen                return EmulateTSTImm(eEncodingT1);
4669e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
4670e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                return false;
4671e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
4672e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingA1:
4673e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 15, 12);
4674e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
4675e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
4676e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
4677e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
4678e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
4679e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                return false;
4680e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
4681e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        default:
4682e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4683e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        }
4684e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4685e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // Read the first operand.
4686157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
4687e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!success)
4688e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4689e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4690e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t result = val1 & imm32;
4691e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4692e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EmulateInstruction::Context context;
4693e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
4694e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.SetNoArgs ();
4695e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4696e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
4697e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4698e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    }
4699e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    return true;
4700e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen}
4701e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4702e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
4703e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// and writes the result to the destination register.  It can optionally update the condition flags
4704e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// based on the result.
4705e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool
4706e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny ChenEmulateInstructionARM::EmulateANDReg (ARMEncoding encoding)
4707e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{
4708e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0
4709e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    // ARM pseudo code...
4710e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if ConditionPassed() then
4711e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EncodingSpecificOperations();
4712e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
4713e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        result = R[n] AND shifted;
4714e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
4715e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
4716e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        else
4717e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            R[d] = result;
4718e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if setflags then
4719e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.N = result<31>;
4720e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.Z = IsZeroBit(result);
4721e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.C = carry;
4722e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                // APSR.V unchanged
4723e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif
4724e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4725e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    bool success = false;
4726e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
4727e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if (!success)
4728e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        return false;
4729e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4730e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if (ConditionPassed())
4731e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    {
4732e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t Rd, Rn, Rm;
4733e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        ARM_ShifterType shift_t;
4734e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
4735e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        bool setflags;
4736e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t carry;
4737e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        switch (encoding)
4738e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        {
4739e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingT1:
4740e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
4741e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rm = Bits32(opcode, 5, 3);
4742e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = !InITBlock();
4743e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            shift_t = SRType_LSL;
4744e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            shift_n = 0;
4745e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingT2:
4746e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 11, 8);
4747e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
4748e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rm = Bits32(opcode, 3, 0);
4749e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
4750157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
4751de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            // if Rd == '1111' && S == '1' then SEE TST (register);
4752e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
4753de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen                return EmulateTSTReg(eEncodingT2);
4754e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
4755e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                return false;
4756e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
4757e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingA1:
4758e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 15, 12);
4759e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
4760e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rm = Bits32(opcode, 3, 0);
4761e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
4762e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
4763e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
4764e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
4765e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                return false;
4766e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
4767e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        default:
4768e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4769e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        }
4770e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4771e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // Read the first operand.
4772157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
4773e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!success)
4774e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4775e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4776e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // Read the second operand.
4777157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
4778e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!success)
4779e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4780e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4781e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
4782e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t result = val1 & shifted;
4783e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4784e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EmulateInstruction::Context context;
4785e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
4786e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.SetNoArgs ();
4787e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
4788e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
4789e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
4790e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    }
4791e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    return true;
4792e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen}
4793e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
47944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
4795e92b27c9262fd185359e6e2184b20d08953485f4Johnny Chen// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
47964d729c559d039181f250e0e3cd444fa73638f26fCaroline Ticebool
47974d729c559d039181f250e0e3cd444fa73638f26fCaroline TiceEmulateInstructionARM::EmulateLDRImmediateARM (ARMEncoding encoding)
47984d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice{
47994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#if 0
48004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    if ConditionPassed() then
48014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        EncodingSpecificOperations();
48024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
48034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        address = if index then offset_addr else R[n];
48044d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        data = MemU[address,4];
48054d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if wback then R[n] = offset_addr;
48064d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if t == 15 then
48074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE;
48084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        elsif UnalignedSupport() || address<1:0> = ’00’ then
48094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            R[t] = data;
48104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else // Can only apply before ARMv7
48114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            R[t] = ROR(data, 8*UInt(address<1:0>));
48124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#endif
48134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    bool success = false;
48154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
48164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    if (!success)
48174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        return false;
48184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    if (ConditionPassed ())
48204d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    {
48214d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
48224d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint32_t t;
48244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint32_t n;
48254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint32_t imm32;
48264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        bool index;
48274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        bool add;
48284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        bool wback;
48294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        switch (encoding)
48314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
48324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            case eEncodingA1:
48334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // if Rn == ’1111’ then SEE LDR (literal);
48344d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // if P == ’0’ && W == ’1’ then SEE LDRT;
48354d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // if Rn == ’1101’ && P == ’0’ && U == ’1’ && W == ’0’ && imm12 == ’000000000100’ then SEE POP;
48364d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
48374d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                t = Bits32 (opcode, 15, 12);
48384d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                n = Bits32 (opcode, 19, 16);
48394d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
48404d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48414d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
48424d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                  index = BitIsSet (opcode, 24);
48434d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                  add = BitIsSet (opcode, 23);
48444d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                  wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
48454d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48464d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // if wback && n == t then UNPREDICTABLE;
48474d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                if (wback && (n == t))
48484d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                    return false;
48494d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48504d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                break;
48514d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48524d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            default:
48534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
48544d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
48554d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48564d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        addr_t address;
48574d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        addr_t offset_addr;
48584d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
48594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (!success)
48604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            return false;
48614d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48624d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
48634d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (add)
48644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                  offset_addr = base_address + imm32;
48654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else
48664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            offset_addr = base_address - imm32;
48674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // address = if index then offset_addr else R[n];
48694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (index)
48704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            address = offset_addr;
48714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else
48724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            address = base_address;
48734d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48744d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // data = MemU[address,4];
48754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        Register base_reg;
48774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
48784d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        EmulateInstruction::Context context;
48804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        context.type = eContextRegisterLoad;
48814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - base_address);
48824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
48844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (!success)
48854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            return false;
48864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // if wback then R[n] = offset_addr;
48884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (wback)
48894d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
48904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.type = eContextAdjustBaseRegister;
48914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.SetAddress (offset_addr);
48924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
48934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
48944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
48954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
48964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // if t == 15 then
48974d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (t == 15)
48984d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
48994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE;
49004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (BitIsClear (address, 1) && BitIsClear (address, 0))
49014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            {
49024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // LoadWritePC (data);
49034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                context.type = eContextRegisterLoad;
49044d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                context.SetRegisterPlusOffset (base_reg, address - base_address);
49054d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                LoadWritePC (context, data);
49064d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            }
49074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            else
49084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                  return false;
49094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
49104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // elsif UnalignedSupport() || address<1:0> = ’00’ then
49114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
49124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
49134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            // R[t] = data;
49144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.type = eContextRegisterLoad;
49154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - base_address);
49164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
49174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
49184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
49194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // else // Can only apply before ARMv7
49204d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else
49214d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
49224d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            // R[t] = ROR(data, 8*UInt(address<1:0>));
49234d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            data = ROR (data, Bits32 (address, 1, 0));
49244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.type = eContextRegisterLoad;
49254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.SetImmediate (data);
49264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
49274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
49284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
49294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
49304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    }
49314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    return true;
49324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice}
49334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
4934fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// LDR (register) calculates an address from a base register value and an offset register value, loads a word
4935fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
4936fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Ticebool
4937fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline TiceEmulateInstructionARM::EmulateLDRRegister (ARMEncoding encoding)
4938fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice{
4939fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#if 0
4940fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    if ConditionPassed() then
4941fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4942fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4943fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4944fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        address = if index then offset_addr else R[n];
4945fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        data = MemU[address,4];
4946fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if wback then R[n] = offset_addr;
4947fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if t == 15 then
4948fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE;
4949fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        elsif UnalignedSupport() || address<1:0> = ’00’ then
4950fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            R[t] = data;
4951fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else // Can only apply before ARMv7
4952fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if CurrentInstrSet() == InstrSet_ARM then
4953fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                R[t] = ROR(data, 8*UInt(address<1:0>));
4954fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
4955fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                R[t] = bits(32) UNKNOWN;
4956fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#endif
4957fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4958fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    bool success = false;
4959fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
4960fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    if (!success)
4961fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        return false;
4962fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4963fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    if (ConditionPassed ())
4964fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    {
4965fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
4966fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4967fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t t;
4968fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t n;
4969fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t m;
4970fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        bool index;
4971fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        bool add;
4972fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        bool wback;
4973fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        ARM_ShifterType shift_t;
4974fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t shift_n;
4975fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4976fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        switch (encoding)
4977fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
4978fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            case eEncodingT1:
4979fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4980fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4981fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                t = Bits32 (opcode, 2, 0);
4982fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                n = Bits32 (opcode, 5, 3);
4983fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                m = Bits32 (opcode, 8, 6);
4984fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4985fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
4986fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                index = true;
4987fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                add = true;
4988fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                wback = false;
4989fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4990fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
4991fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_t = SRType_LSL;
4992fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_n = 0;
4993fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4994fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                break;
4995fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
4996fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            case eEncodingT2:
4997fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if Rn == ’1111’ then SEE LDR (literal);
4998fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4999fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                t = Bits32 (opcode, 15, 12);
5000fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                n = Bits32 (opcode, 19, 16);
5001fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                m = Bits32 (opcode, 3, 0);
5002fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5003fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
5004fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                index = true;
5005fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                add = true;
5006fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                wback = false;
5007fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5008fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5009fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_t = SRType_LSL;
5010fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
5011fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5012fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if BadReg(m) then UNPREDICTABLE;
5013fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (BadReg (m))
5014fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5015fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5016fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5017fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if ((t == 15) && InITBlock() && !LastInITBlock())
5018fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5019fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5020fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                break;
5021fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5022fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            case eEncodingA1:
5023fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
5024fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if P == ’0’ && W == ’1’ then SEE LDRT;
5025fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5026fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                t = Bits32 (opcode, 15, 12);
5027fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                n = Bits32 (opcode, 19, 16);
5028fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                m = Bits32 (opcode, 3, 0);
5029fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5030fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
5031fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                index = BitIsSet (opcode, 24);
5032fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                add = BitIsSet (opcode, 23);
5033fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5034fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5035fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5036fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                uint32_t type = Bits32 (opcode, 6, 5);
5037fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
5038fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_n = DecodeImmShift (type, imm5, shift_t);
5039fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5040fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if m == 15 then UNPREDICTABLE;
5041fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (m == 15)
5042fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5043fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5044fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5045fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (wback && ((n == 15) || (n == t)))
5046fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5047fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
5048fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                break;
5049fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5050fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5051fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            default:
5052fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
5053fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
5054fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5055fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5056fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (!success)
5057fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            return false;
5058fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5059fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5060fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (!success)
5061fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            return false;
5062fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5063fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        addr_t offset_addr;
5064fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        addr_t address;
5065fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5066fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
5067fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_inst_cpsr, CPSR_C));
5068fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5069fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5070fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (add)
5071fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            offset_addr = Rn + offset;
5072fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else
5073fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            offset_addr = Rn - offset;
5074fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5075fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // address = if index then offset_addr else R[n];
5076fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (index)
5077fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                address = offset_addr;
5078fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
5079fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                address = Rn;
5080fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5081fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // data = MemU[address,4];
5082fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        Register base_reg;
5083fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5084fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5085fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        EmulateInstruction::Context context;
5086fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        context.type = eContextRegisterLoad;
5087fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
5088fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5089fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5090fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (!success)
5091fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            return false;
5092fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5093fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // if wback then R[n] = offset_addr;
5094fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (wback)
5095fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
5096fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.type = eContextAdjustBaseRegister;
5097fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.SetAddress (offset_addr);
5098fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5099fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
5100fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
5101fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5102fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // if t == 15 then
5103fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (t == 15)
5104fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
5105fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            // if address<1:0> == ’00’ then LoadWritePC(data); else UNPREDICTABLE;
5106fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5107fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
5108fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.type = eContextRegisterLoad;
5109fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.SetRegisterPlusOffset (base_reg, address - Rn);
5110fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                LoadWritePC (context, data);
5111fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
5112fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
5113fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
5114fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
5115fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // elsif UnalignedSupport() || address<1:0> = ’00’ then
5116fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5117fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
5118fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            // R[t] = data;
5119fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.type = eContextRegisterLoad;
5120fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - Rn);
5121fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5122fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
5123fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
5124fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else // Can only apply before ARMv7
5125fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
5126fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            // if CurrentInstrSet() == InstrSet_ARM then
5127fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (CurrentInstrSet () == eModeARM)
5128fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
5129fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // R[t] = ROR(data, 8*UInt(address<1:0>));
5130fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                data = ROR (data, Bits32 (address, 1, 0));
5131fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.type = eContextRegisterLoad;
5132fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.SetImmediate (data);
5133fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5134fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5135fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
5136fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
5137fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
5138fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // R[t] = bits(32) UNKNOWN;
5139fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                WriteBits32Unknown (t);
5140fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
5141fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
5142fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    }
5143fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    return true;
5144fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice}
514521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
514621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice// LDRB (immediate, Thumb)
514721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Ticebool
514821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline TiceEmulateInstructionARM::EmulateLDRBImmediate (ARMEncoding encoding)
514921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice{
515021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#if 0
515121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    if ConditionPassed() then
515221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
515321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
515421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        address = if index then offset_addr else R[n];
515521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        R[t] = ZeroExtend(MemU[address,1], 32);
515621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if wback then R[n] = offset_addr;
515721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#endif
515821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
515921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    bool success = false;
516021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
516121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    if (!success)
516221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        return false;
516321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
516421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    if (ConditionPassed ())
516521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    {
516621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t t;
516721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t n;
516821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t imm32;
516921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        bool index;
517021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        bool add;
517121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        bool wback;
517221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
517321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
517421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        switch (encoding)
517521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        {
517621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            case eEncodingT1:
517721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
517821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                t = Bits32 (opcode, 2, 0);
517921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                n = Bits32 (opcode, 5, 3);
518021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                imm32 = Bits32 (opcode, 10, 6);
518121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
518221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
518321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                index = true;
518421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                add = true;
518521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                wback= false;
518621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
518721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                break;
518821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
518921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            case eEncodingT2:
519021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if Rt == ’1111’ then SEE PLD;
519121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if Rn == ’1111’ then SEE LDRB (literal);
519221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
519321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                t = Bits32 (opcode, 15, 12);
519421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                n = Bits32 (opcode, 19, 16);
519521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
519621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
519721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
519821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                index = true;
519921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                add = true;
520021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                wback = false;
520121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
520221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if t == 13 then UNPREDICTABLE;
520321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                if (t == 13)
520421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                    return false;
520521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
520621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                break;
520721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
520821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            case eEncodingT3:
520921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if Rt == ’1111’ && P == ’1’ && U == ’0’ && W == ’0’ then SEE PLD;
521021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if Rn == ’1111’ then SEE LDRB (literal);
521121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE LDRBT;
521221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if P == ’0’ && W == ’0’ then UNDEFINED;
521321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
521421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                    return false;
521521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
521621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
521721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                t = Bits32 (opcode, 15, 12);
521821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                n = Bits32 (opcode, 19, 16);
521921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                imm32 = Bits32 (opcode, 7, 0);
522021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
522121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
522221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                index = BitIsSet (opcode, 10);
522321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                add = BitIsSet (opcode, 9);
522421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                wback = BitIsSet (opcode, 8);
522521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
522621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
522721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                if (BadReg (t) || (wback && (n == t)))
522821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                    return false;
522921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
523021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                break;
523121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
523221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            default:
523321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                return false;
523421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        }
523521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
523621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
523721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (!success)
523821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            return false;
523921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
524021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        addr_t address;
524121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        addr_t offset_addr;
524221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
524321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
524421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (add)
524521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            offset_addr = Rn + imm32;
524621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        else
524721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            offset_addr = Rn - imm32;
524821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
524921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // address = if index then offset_addr else R[n];
525021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (index)
525121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            address = offset_addr;
525221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        else
525321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            address = Rn;
525421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
525521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // R[t] = ZeroExtend(MemU[address,1], 32);
525621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        Register base_reg;
525721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        Register data_reg;
525821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
525921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
526021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
526121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        EmulateInstruction::Context context;
526221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        context.type = eContextRegisterLoad;
526321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
526421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
526521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint64_t data = MemURead (context, address, 1, 0, &success);
526621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (!success)
526721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            return false;
526821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
526921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
527021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            return false;
527121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
527221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // if wback then R[n] = offset_addr;
527321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (wback)
527421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        {
527521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            context.type = eContextAdjustBaseRegister;
527621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            context.SetAddress (offset_addr);
527721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
527821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                return false;
527921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        }
528021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    }
528121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    return true;
528221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice}
5283f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5284f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
5285f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// zero-extends it to form a 32-bit word and writes it to a register.
5286f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Ticebool
5287f55261f53d56b4911c4c1ce419d893e5250d7150Caroline TiceEmulateInstructionARM::EmulateLDRBLiteral (ARMEncoding encoding)
5288f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice{
5289f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#if 0
5290f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    if ConditionPassed() then
5291f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
5292f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        base = Align(PC,4);
5293f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        address = if add then (base + imm32) else (base - imm32);
5294f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        R[t] = ZeroExtend(MemU[address,1], 32);
5295f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#endif
5296f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5297f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    bool success = false;
5298f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
5299f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    if (!success)
5300f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        return false;
5301f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5302f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    if (ConditionPassed ())
5303f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    {
5304f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t t;
5305f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t imm32;
5306f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        bool add;
5307f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        switch (encoding)
5308f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        {
5309f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            case eEncodingT1:
5310f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // if Rt == ’1111’ then SEE PLD;
5311f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’);
5312f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                t = Bits32 (opcode, 15, 12);
5313f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
5314f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                add = BitIsSet (opcode, 23);
5315f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5316f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // if t == 13 then UNPREDICTABLE;
5317f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                if (t == 13)
5318f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                    return false;
5319f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5320f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                break;
5321f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5322f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            case eEncodingA1:
5323f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == ’1’);
5324f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                t = Bits32 (opcode, 15, 12);
5325f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
5326f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                add = BitIsSet (opcode, 23);
5327f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5328f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // if t == 15 then UNPREDICTABLE;
5329f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                if (t == 15)
5330f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                    return false;
5331f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                break;
5332f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5333f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            default:
5334f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                return false;
5335f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        }
5336f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5337f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        // base = Align(PC,4);
5338f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t pc_val = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
5339f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (!success)
5340f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            return false;
5341f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5342f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t base = AlignPC (pc_val);
5343f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5344f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        addr_t address;
5345f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        // address = if add then (base + imm32) else (base - imm32);
5346f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (add)
5347f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            address = base + imm32;
5348f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        else
5349f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            address = base - imm32;
5350f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5351f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        // R[t] = ZeroExtend(MemU[address,1], 32);
5352f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        EmulateInstruction::Context context;
5353f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        context.type = eContextRelativeBranchImmediate;
5354f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        context.SetImmediate (address - base);
5355f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5356f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint64_t data = MemURead (context, address, 1, 0, &success);
5357f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (!success)
5358f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            return false;
5359f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
5360f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5361f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            return false;
5362f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    }
5363f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    return true;
5364f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice}
536530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
536630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
536730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
536830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// optionally be shifted.
536930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Ticebool
537030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline TiceEmulateInstructionARM::EmulateLDRBRegister (ARMEncoding encoding)
537130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice{
537230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#if 0
537330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    if ConditionPassed() then
537430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
537530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
537630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
537730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        address = if index then offset_addr else R[n];
537830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        R[t] = ZeroExtend(MemU[address,1],32);
537930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if wback then R[n] = offset_addr;
538030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#endif
538130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
538230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    bool success = false;
538330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
538430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    if (!success)
538530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        return false;
538630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
538730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    if (ConditionPassed ())
538830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    {
538930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t t;
539030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t n;
539130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t m;
539230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        bool index;
539330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        bool add;
539430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        bool wback;
539530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        ARM_ShifterType shift_t;
539630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t shift_n;
539730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
539830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
539930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        switch (encoding)
540030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        {
540130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            case eEncodingT1:
540230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
540330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                t = Bits32 (opcode, 2, 0);
540430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                n = Bits32 (opcode, 5, 3);
540530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                m = Bits32 (opcode, 8, 6);
540630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
540730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
540830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                index = true;
540930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                add = true;
541030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                wback = false;
541130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
541230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
541330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_t = SRType_LSL;
541430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_n = 0;
541530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                break;
541630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
541730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            case eEncodingT2:
541830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if Rt == ’1111’ then SEE PLD;
541930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if Rn == ’1111’ then SEE LDRB (literal);
542030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
542130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                t = Bits32 (opcode, 15, 12);
542230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                n = Bits32 (opcode, 19, 16);
542330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                m = Bits32 (opcode, 3, 0);
542430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
542530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
542630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                index = true;
542730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                add = true;
542830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                wback = false;
542930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
543030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
543130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_t = SRType_LSL;
543230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
543330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
543430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if t == 13 || BadReg(m) then UNPREDICTABLE;
543530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                if ((t == 13) || BadReg (m))
543630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                    return false;
543730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                break;
543830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
543930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            case eEncodingA1:
544030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            {
544130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if P == ’0’ && W == ’1’ then SEE LDRBT;
544230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
544330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                t = Bits32 (opcode, 15, 12);
544430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                n = Bits32 (opcode, 19, 16);
544530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                m = Bits32 (opcode, 3, 0);
544630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
544730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
544830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                index = BitIsSet (opcode, 24);
544930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                add = BitIsSet (opcode, 23);
545030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
545130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
545230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
545330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                uint32_t type = Bits32 (opcode, 6, 5);
545430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
545530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_n = DecodeImmShift (type, imm5, shift_t);
545630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
545730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if t == 15 || m == 15 then UNPREDICTABLE;
545830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                if ((t == 15) || (m == 15))
545930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                    return false;
546030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
546130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
546230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                if (wback && ((n == 15) || (n == t)))
546330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                    return false;
546430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            }
546530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                break;
546630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
546730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            default:
546830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                return false;
546930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        }
547030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
547130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        addr_t offset_addr;
547230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        addr_t address;
547330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
547430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
547530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
547630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!success)
547730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
547830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
547930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
548030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
548130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
548230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
548330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!success)
548430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
548530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
548630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (add)
548730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            offset_addr = Rn + offset;
548830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        else
548930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            offset_addr = Rn - offset;
549030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
549130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // address = if index then offset_addr else R[n];
549230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (index)
549330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            address = offset_addr;
549430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        else
549530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            address = Rn;
549630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
549730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // R[t] = ZeroExtend(MemU[address,1],32);
549830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        Register base_reg;
549930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
550030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
550130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        EmulateInstruction::Context context;
550230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        context.type = eContextRegisterLoad;
550330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
550430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
550530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint64_t data = MemURead (context, address, 1, 0, &success);
550630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!success)
550730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
550830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
550930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
551030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
551130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
551230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // if wback then R[n] = offset_addr;
551330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (wback)
551430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        {
551530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            context.type = eContextAdjustBaseRegister;
551630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            context.SetAddress (offset_addr);
551730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
551830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                return false;
551930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        }
552030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    }
552130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    return true;
552230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice}
5523fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
55242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
55252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// and writes the result to the destination register.  It can optionally update the condition flags based on
55262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result.
55272115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
55282115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateEORImm (ARMEncoding encoding)
55292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
55302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
55312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
55322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
55332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
55342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR imm32;
55352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
55362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
55372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        else
55382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            R[d] = result;
55392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if setflags then
55402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.N = result<31>;
55412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.Z = IsZeroBit(result);
55422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.C = carry;
55432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                // APSR.V unchanged
55442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
55452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
55462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
55472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
55482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (!success)
55492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        return false;
55502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
55512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (ConditionPassed())
55522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
55532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rd, Rn;
55542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
55552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        bool setflags;
55562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
55572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
55582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
55592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
55602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 11, 8);
55612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
55622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
55632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
55642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
55652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
55662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return EmulateTEQImm(eEncodingT1);
55672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
55682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
55692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
55702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
55712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 15, 12);
55722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
55732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
55742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
55752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
55762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
55772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
55782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
55792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
55802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
55812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
55822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
55832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
55842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
55852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
55862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
55872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
55882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
55892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ imm32;
55902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
55912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
55922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
55932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
55942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
55952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
55962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
55972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
55982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
55992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
56002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
56022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value, and writes the result to the destination register.
56032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// It can optionally update the condition flags based on the result.
56042115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
56052115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateEORReg (ARMEncoding encoding)
56062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
56072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
56082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
56092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
56102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
56112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
56122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR shifted;
56132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
56142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
56152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        else
56162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            R[d] = result;
56172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if setflags then
56182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.N = result<31>;
56192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.Z = IsZeroBit(result);
56202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.C = carry;
56212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                // APSR.V unchanged
56222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
56232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
56252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
56262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (!success)
56272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        return false;
56282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (ConditionPassed())
56302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
56312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rd, Rn, Rm;
56322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        ARM_ShifterType shift_t;
56332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
56342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        bool setflags;
56352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry;
56362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
56372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
56382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
56392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
56402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 5, 3);
56412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = !InITBlock();
56422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_t = SRType_LSL;
56432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_n = 0;
56442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT2:
56452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 11, 8);
56462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
56472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
56482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
56492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
56502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == ‘1111’ && S == ‘1’ then SEE TEQ (register);
56512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
56522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return EmulateTEQReg(eEncodingT1);
56532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
56542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
56552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
56562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
56572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 15, 12);
56582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
56592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
56602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
56612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
56622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
56632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
56642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
56652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
56662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
56672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
56682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
56692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
56702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
56722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
56732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
56742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
56752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the second operand.
56772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
56782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
56792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
56802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
56822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ shifted;
56832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
56852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
56862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
56872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
56892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
56902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
56912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
56922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
56932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
56947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
56957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// writes the result to the destination register.  It can optionally update the condition flags based
56967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result.
56977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool
56987c5234db18ead0935e884429b3cace95b3a9dce4Johnny ChenEmulateInstructionARM::EmulateORRImm (ARMEncoding encoding)
56997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{
57007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0
57017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    // ARM pseudo code...
57027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if ConditionPassed() then
57037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EncodingSpecificOperations();
57047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        result = R[n] OR imm32;
57057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
57067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
57077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        else
57087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            R[d] = result;
57097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if setflags then
57107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.N = result<31>;
57117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.Z = IsZeroBit(result);
57127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.C = carry;
57137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                // APSR.V unchanged
57147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif
57157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    bool success = false;
57177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
57187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if (!success)
57197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        return false;
57207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if (ConditionPassed())
57227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    {
57237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t Rd, Rn;
57247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
57257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        bool setflags;
57267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
57277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        switch (encoding)
57287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        {
57297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT1:
57307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
57317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
57327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
57337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
57347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // if Rn == ‘1111’ then SEE MOV (immediate);
57357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rn == 15)
57367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return EmulateMOVRdImm(eEncodingT2);
57377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (BadReg(Rd) || Rn == 13)
57387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
57397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
57407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingA1:
57417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 15, 12);
57427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
57437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
57447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
57457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
57467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rd == 15 && setflags)
57477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
57487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
57497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        default:
57507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
57517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        }
57527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // Read the first operand.
57547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
57557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!success)
57567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
57577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t result = val1 | imm32;
57597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EmulateInstruction::Context context;
57617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
57627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.SetNoArgs ();
57637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
57657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
57667c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    }
57677c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    return true;
57687c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen}
57697c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
57717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// value, and writes the result to the destination register.  It can optionally update the condition flags based
57727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result.
57737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool
57747c5234db18ead0935e884429b3cace95b3a9dce4Johnny ChenEmulateInstructionARM::EmulateORRReg (ARMEncoding encoding)
57757c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{
57767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0
57777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    // ARM pseudo code...
57787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if ConditionPassed() then
57797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EncodingSpecificOperations();
57807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
57817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        result = R[n] OR shifted;
57827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
57837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
57847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        else
57857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            R[d] = result;
57867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if setflags then
57877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.N = result<31>;
57887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.Z = IsZeroBit(result);
57897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.C = carry;
57907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                // APSR.V unchanged
57917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif
57927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57937c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    bool success = false;
57947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
57957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if (!success)
57967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        return false;
57977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
57987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if (ConditionPassed())
57997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    {
58007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t Rd, Rn, Rm;
58017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        ARM_ShifterType shift_t;
58027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
58037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        bool setflags;
58047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t carry;
58057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        switch (encoding)
58067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        {
58077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT1:
58087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
58097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 5, 3);
58107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = !InITBlock();
58117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            shift_t = SRType_LSL;
58127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            shift_n = 0;
58137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT2:
58147c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
58157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
58167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 3, 0);
58177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
58187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
58197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // if Rn == ‘1111’ then SEE MOV (register);
58207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rn == 15)
58217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return EmulateMOVRdRm(eEncodingT3);
58227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
58237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
58247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
58257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingA1:
58267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 15, 12);
58277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
58287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 3, 0);
58297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
58307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
58317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // TODO: Emulate SUBS PC, LR and related instructions.
58327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rd == 15 && setflags)
58337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
58347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
58357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        default:
58367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
58377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        }
58387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
58397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // Read the first operand.
58407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
58417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!success)
58427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
58437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
58447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // Read the second operand.
58457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
58467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!success)
58477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
58487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
58497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
58502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 | shifted;
58517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
58527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EmulateInstruction::Context context;
58537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
58547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.SetNoArgs ();
58557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
58567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
58577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
58587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    }
58597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    return true;
58607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen}
58617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
58622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
58632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// immediate value.  It updates the condition flags based on the result, and discards the result.
58642115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
58652115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateTEQImm (ARMEncoding encoding)
58662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
58672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
58682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
58692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
58702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
58712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR imm32;
58722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.N = result<31>;
58732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.Z = IsZeroBit(result);
58742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.C = carry;
58752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // APSR.V unchanged
58762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
58772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
58782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
58792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
58802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (!success)
58812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        return false;
58822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
58832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (ConditionPassed())
58842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
58852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rn;
58862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
58872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
58882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
58892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
58902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
58912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
58922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
58932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (BadReg(Rn))
58942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
58952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
58962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
58972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
58982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
58992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
59002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
59012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
59032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
59052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
59062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
59072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ imm32;
59102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
59122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
59132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
59142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteFlags(context, result, carry))
59162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
59182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
59192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
59202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
59222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value.  It updates the condition flags based on the result, and discards
59232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result.
59242115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
59252115b4131b0e427341959fb4007e0173bf71778dJohnny ChenEmulateInstructionARM::EmulateTEQReg (ARMEncoding encoding)
59262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
59272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
59282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
59292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
59302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
59312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
59322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR shifted;
59332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.N = result<31>;
59342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.Z = IsZeroBit(result);
59352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.C = carry;
59362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // APSR.V unchanged
59372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
59382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
59402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
59412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (!success)
59422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        return false;
59432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if (ConditionPassed())
59452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
59462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rn, Rm;
59472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        ARM_ShifterType shift_t;
59482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
59492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry;
59502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
59512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
59522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
59532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
59542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
59552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
59562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (BadReg(Rn) || BadReg(Rm))
59572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
59582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
59592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
59602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
59612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
59622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
59632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
59642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
59652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
59672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
59692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
59702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
59712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the second operand.
59742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
59752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
59762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
59792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ shifted;
59802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
59822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
59832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
59842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
59852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteFlags(context, result, carry))
59862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
59872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
59882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
59892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
59902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
5991de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
5992de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result.
5993de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool
5994de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny ChenEmulateInstructionARM::EmulateTSTImm (ARMEncoding encoding)
5995de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{
5996de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0
5997de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    // ARM pseudo code...
5998de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if ConditionPassed() then
5999de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EncodingSpecificOperations();
6000de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        result = R[n] AND imm32;
6001de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.N = result<31>;
6002de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.Z = IsZeroBit(result);
6003de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.C = carry;
6004de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // APSR.V unchanged
6005de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif
6006de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6007de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    bool success = false;
6008de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
6009de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if (!success)
6010de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        return false;
6011de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6012de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if (ConditionPassed())
6013de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    {
6014de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t Rn;
6015de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
6016de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
6017de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        switch (encoding)
6018de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        {
6019de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingT1:
6020de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
6021de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
6022de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            if (BadReg(Rn))
6023de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen                return false;
6024de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
6025de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingA1:
6026de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
6027de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
6028de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
6029de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        default:
6030de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6031de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        }
6032de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6033de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // Read the first operand.
6034de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
6035de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!success)
6036de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6037de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6038de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t result = val1 & imm32;
6039de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6040de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EmulateInstruction::Context context;
6041de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
6042de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.SetNoArgs ();
6043de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6044de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!WriteFlags(context, result, carry))
6045de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6046de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    }
6047de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    return true;
6048de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen}
6049de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6050de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
6051de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result.
6052de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool
6053de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny ChenEmulateInstructionARM::EmulateTSTReg (ARMEncoding encoding)
6054de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{
6055de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0
6056de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    // ARM pseudo code...
6057de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if ConditionPassed() then
6058de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EncodingSpecificOperations();
6059de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
6060de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        result = R[n] AND shifted;
6061de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.N = result<31>;
6062de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.Z = IsZeroBit(result);
6063de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.C = carry;
6064de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // APSR.V unchanged
6065de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif
6066de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6067de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    bool success = false;
6068de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
6069de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if (!success)
6070de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        return false;
6071de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6072de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if (ConditionPassed())
6073de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    {
6074de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t Rn, Rm;
6075de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        ARM_ShifterType shift_t;
6076de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
6077de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t carry;
6078de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        switch (encoding)
6079de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        {
6080de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingT1:
6081de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 2, 0);
6082de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rm = Bits32(opcode, 5, 3);
6083de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            shift_t = SRType_LSL;
6084de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            shift_n = 0;
6085de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingT2:
6086de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
6087de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rm = Bits32(opcode, 3, 0);
6088de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
6089de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            if (BadReg(Rn) || BadReg(Rm))
6090de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen                return false;
6091de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
6092de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingA1:
6093de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
6094de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rm = Bits32(opcode, 3, 0);
6095de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
6096de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
6097de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        default:
6098de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6099de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        }
6100de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6101de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // Read the first operand.
6102de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
6103de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!success)
6104de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6105de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6106de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // Read the second operand.
6107de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
6108de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!success)
6109de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6110de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6111de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
6112de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t result = val1 & shifted;
6113de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6114de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EmulateInstruction::Context context;
6115de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
6116de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.SetNoArgs ();
6117de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6118de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!WriteFlags(context, result, carry))
6119de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
6120de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    }
6121de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    return true;
6122de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen}
6123de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
61242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode*
61252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
612664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
61272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static ARMOpcode
61282b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    g_arm_opcodes[] =
61292b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
61302b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
61312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Prologue instructions
61322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
61332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push register(s)
61359f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
61369f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
61372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // set r7 to point to a stack offset
61399f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
6140864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
6141e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // copy the stack pointer to ip
61429f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
61439f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
6144864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
61452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // adjust the stack pointer
6147864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
61482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push one register
61502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
6151c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0x0fff0000, 0x052d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
61522b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61532b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // vector push consecutive extension register(s)
61549b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
61559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
61562b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
6158587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        // Epilogue instructions
61592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
61602b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
61619f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
61629f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
61639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
6164b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
6165b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
6166b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
6167b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        // Supervisor Call (previously Software Interrupt)
6168b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
61693b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
61703b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
61713b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
61723b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // Branch instructions
61733b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
6174b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"},
6175383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
6176383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
6177383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
6178383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
6179ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        // for example, "bx lr"
6180ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
6181b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
6182b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
618328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        // Data-processing instructions
618428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        //----------------------------------------------------------------------
6185157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (immediate)
6186157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
6187157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (register)
6188157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
61898fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        // add (immediate)
6190157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
61918fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        // add (register)
6192157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
6193e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (immediate)
6194157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
6195e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (register)
6196157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
61972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (immediate)
61982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
61992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (register)
62002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
62017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (immediate)
62027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
62037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (register)
62047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
62052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (immediate)
62062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
62072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (register)
62082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
6209de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (immediate)
6210de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
6211de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (register)
6212de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
6213de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6214de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
6215d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (immediate)
6216d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
6217d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (register)
6218d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
62193847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen        // cmn (immediate)
62203847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
62213847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen        // cmn (register)
62223847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
622334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (immediate)
622434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
622534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (register)
622634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
622782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // asr (immediate)
622882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
62292ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // asr (register)
6230e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
62312ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (immediate)
62322ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
62332ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (register)
62342ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
62352ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (immediate)
62362ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
62372ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (register)
62382ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
6239eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // rrx is a special case encoding of ror (immediate)
6240eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
6241eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (immediate)
6242eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
6243eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (register)
6244eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
624528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen
624628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        //----------------------------------------------------------------------
6247b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        // Load instructions
6248b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
62490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
6250713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
625185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
6252fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
62534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
6254fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
625530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
625630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
6257fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
6258fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
6259fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // Store instructions
6260fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
62611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        { 0x0fd00000, 0x08800000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
6262b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        { 0x0fd00000, 0x08000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
6263af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        { 0x0fd00000, 0x09000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
62643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        { 0x0fd00000, 0x09800000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
62653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        { 0x0e500010, 0x06000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }
62661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
6267b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
62682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    };
62692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
62702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
62712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    for (size_t i=0; i<k_num_arm_opcodes; ++i)
62722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
62732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
62742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            return &g_arm_opcodes[i];
62752b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    }
62762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    return NULL;
62772b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
62782b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
62792b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
62802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode*
62812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
6282347320d16d98cffaadf3f888569100c43b241068Johnny Chen{
62832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
62842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static ARMOpcode
62852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    g_thumb_opcodes[] =
62862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
62872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
62882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Prologue instructions
62892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
62902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
62912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push register(s)
62929f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
62939f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
62949f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
62952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
62962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // set r7 to point to a stack offset
62979f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
6298e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // copy the stack pointer to r7
62999f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
6300e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
63019f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
63022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
6303864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        // PC-relative load into register (see also EmulateADDSPRm)
6304c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
63052b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
63062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // adjust the stack pointer
6307864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
6308864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "add sp, sp, #imm"},
6309864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
6310864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
63112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
63122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // vector push consecutive extension register(s)
6313d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
6314d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
63152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
63162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
63172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Epilogue instructions
63182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
63192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
6320864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
63219f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
63229f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
63239f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
6324d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
6325d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
6326b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
6327b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
6328b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        // Supervisor Call (previously Software Interrupt)
6329b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
6330c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
6331c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
6332c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        //----------------------------------------------------------------------
6333c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        // If Then makes up to four following instructions conditional.
6334c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        //----------------------------------------------------------------------
63353b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
63363b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
63373b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
63383b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // Branch instructions
63393b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
63403b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
63413b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
63423b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0xffff8000, 0x0000e000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"},
63439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
6344b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"},
6345383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // J1 == J2 == 1
6346383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xf800f800, 0xf000f800, ARMV4T_ABOVE,  eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
6347383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // J1 == J2 == 1
6348383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xf800e800, 0xf000e800, ARMV5_ABOVE,   eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
6349383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
6350ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        // for example, "bx lr"
6351ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
635253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        // compare and branch
635353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
635460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        // table branch byte
635560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
635660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        // table branch halfword
635760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
6358b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
6359b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
636026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Data-processing instructions
636126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        //----------------------------------------------------------------------
6362157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (immediate)
6363157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
6364157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (register)
6365157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
6366157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
6367157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // add (register)
63689f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
636926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
63709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
6371e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (immediate)
6372157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
6373e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (register)
6374e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
6375e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
63762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (immediate)
63772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
63782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (register)
63792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
63802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
63817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (immediate)
63827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
63837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (register)
63847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
63857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
63862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (immediate)
63872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
63882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (register)
63892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
6390de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (immediate)
63912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
6392de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (register)
6393de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
6394de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
6395de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
63967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
6397338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        // move from high register to high register
63989f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
6399338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        // move from low register to low register
64009f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
64017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // mov{s}<c>.w <Rd>, <Rm>
64027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
6403357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        // move immediate
64049f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
64059f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
6406d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (immediate)
6407d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
6408d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (register)
6409d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
6410d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
641134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmn (immediate)
6412688926f8fb9a56964249ec970b4ae313a5b366d4Johnny Chen        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
641334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmn (register)
641434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
641534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0xfff08f00, 0xeb100f00, ARMvAll,       eEncodingT2, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
641634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (immediate)
641734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
641834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (register) (Rn and Rm both from r0-r7)
641934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
642034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (register) (Rn and Rm not both from r0-r7)
642134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
642282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // asr (immediate)
642382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
64244d896db529a5fef200333ef673976528319279bdJohnny Chen        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
6425e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // asr (register)
6426e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
6427e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
64282ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (immediate)
64292ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
64302ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
64312ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (register)
64322ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
64332ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
64342ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (immediate)
64352ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
64362ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
64372ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (register)
6438eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
64392ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
6440eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // rrx is a special case encoding of ror (immediate)
6441eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
6442eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (immediate)
6443eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
6444eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (register)
6445eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
6446eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
644726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
644826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        //----------------------------------------------------------------------
6449b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        // Load instructions
6450b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
6451b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
64520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
6453ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
6454c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        { 0xfffff800, 0x00006800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
6455c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        // Thumb2 PC-relative load into register
6456fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
6457fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
6458fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
645921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
646021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
646121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[>Rn>, #+/-<imm8>]{!}" },
6462f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
646330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
646430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        {  0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, eSize32,&EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
6465fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
6466fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
6467fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // Store instructions
6468fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
6469fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
6470b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
64717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
6472fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
6473fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
6474fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
6475fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
6476fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
6477fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
6478fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
6479fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
6480fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }
64812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    };
64822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
64832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
64842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
64852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
64862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
64872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            return &g_thumb_opcodes[i];
64882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    }
64892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    return NULL;
64902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
649164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
649231e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool
6493395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
649431e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{
649531e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    m_arm_isa = 0;
6496395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    const char *arch_cstr = arch.AsCString ();
6497395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    if (arch_cstr)
6498395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    {
6499395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
6500395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
6501395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
6502395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
6503395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
6504395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
6505395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
6506395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
6507395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
6508395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
650931e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    }
651031e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    return m_arm_isa != 0;
651131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton}
651231e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton
651331e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton
651464c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
651564c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction ()
651664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
651764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool success = false;
651864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
651964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (success)
652064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
652164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
652264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (success)
652364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
65249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Context read_inst_context;
65259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            read_inst_context.type = eContextReadOpcode;
65269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            read_inst_context.SetNoArgs ();
65279bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
652864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (m_inst_cpsr & MASK_CPSR_T)
652964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
653064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                m_inst_mode = eModeThumb;
6531cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
653264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
653364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if (success)
653464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                {
653564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0))
653664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    {
653764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                        m_inst.opcode_type = eOpcode16;
653864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                        m_inst.opcode.inst16 = thumb_opcode;
653964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    }
654064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    else
654164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    {
654264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                        m_inst.opcode_type = eOpcode32;
6543cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                        m_inst.opcode.inst32 = (thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success);
654464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    }
654564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                }
654664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
654764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            else
654864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
654964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                m_inst_mode = eModeARM;
655064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                m_inst.opcode_type = eOpcode32;
6551cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                m_inst.opcode.inst32 = MemARead(read_inst_context, pc, 4, 0, &success);
655264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
655364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
655464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
655564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (!success)
655664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
655764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        m_inst_mode = eModeInvalid;
655864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        m_inst_pc = LLDB_INVALID_ADDRESS;
655964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
656064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return success;
656164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
656264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
6563ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t
6564ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion ()
6565ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
6566ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return m_arm_isa;
6567ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
6568ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
656964c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
657064c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ConditionPassed ()
657164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
657264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (m_inst_cpsr == 0)
657364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
657464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
657564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    const uint32_t cond = CurrentCond ();
657664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
657764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (cond == UINT32_MAX)
657864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
657964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
658064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool result = false;
658164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    switch (UnsignedBits(cond, 3, 1))
658264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
658364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break;
658464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break;
658564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break;
658664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break;
658764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break;
658864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 5:
658964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
659064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool n = (m_inst_cpsr & MASK_CPSR_N);
659164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool v = (m_inst_cpsr & MASK_CPSR_V);
659264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            result = n == v;
659364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
659464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
659564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 6:
659664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
659764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool n = (m_inst_cpsr & MASK_CPSR_N);
659864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool v = (m_inst_cpsr & MASK_CPSR_V);
659964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0);
660064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
660164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
660264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 7:
660364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        result = true;
660464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
660564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
660664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
660764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (cond & 1)
660864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        result = !result;
660964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return result;
661064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
661164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
66129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t
66139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::CurrentCond ()
66149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
66159ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    switch (m_inst_mode)
66169ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
66179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    default:
66189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeInvalid:
66199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        break;
66209ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
66219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeARM:
66229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return UnsignedBits(m_inst.opcode.inst32, 31, 28);
66239ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
66249ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeThumb:
66259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
66269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        // 'cond' field of the encoding.
66279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (m_inst.opcode_type == eOpcode16 &&
66289ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d &&
66299ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f)
66309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        {
66319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return Bits32(m_inst.opcode.inst16, 11, 7);
66329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
66339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        else if (m_inst.opcode_type == eOpcode32 &&
66349ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e &&
66359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 &&
66369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 &&
66379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d)
66389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        {
66399ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return Bits32(m_inst.opcode.inst32, 25, 22);
66409ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
66419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
66429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return m_it_session.GetCond();
66439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
66449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    return UINT32_MAX;  // Return invalid value
66459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
66469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
66479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool
6648098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock()
6649098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{
6650098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
6651098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen}
6652098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen
6653098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool
6654098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock()
6655098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{
6656098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
6657098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen}
6658098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen
6659098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool
66609ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
66619ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
66629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    addr_t target;
66639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
6664ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    // Check the current instruction set.
6665ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    if (CurrentInstrSet() == eModeARM)
66669ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffc;
6667ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    else
66689ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffe;
6669ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
66709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
667153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
667253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
667353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
66749ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
66759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
66769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
66779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool
6678668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
66799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
66809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    addr_t target;
66810f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
66820f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // we want to record it and issue a WriteRegister callback so the clients
66830f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // can track the mode changes accordingly.
66840f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    bool cpsr_changed = false;
66859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
66869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (BitIsSet(addr, 0))
66879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
66880f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        if (CurrentInstrSet() != eModeThumb)
66890f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        {
66900f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            SelectInstrSet(eModeThumb);
66910f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            cpsr_changed = true;
66920f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        }
66939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffe;
6694668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetMode (eModeThumb);
66959ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
66969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    else if (BitIsClear(addr, 1))
66979ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
66980f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        if (CurrentInstrSet() != eModeARM)
66990f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        {
67000f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            SelectInstrSet(eModeARM);
67010f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            cpsr_changed = true;
67020f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        }
67039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffc;
6704668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetMode (eModeARM);
67059ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
67069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    else
67079ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return false; // address<1:0> == '10' => UNPREDICTABLE
67089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
67090f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    if (cpsr_changed)
67100f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    {
6711558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
67120f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            return false;
67130f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    }
67149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
671553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
671653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
671753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
67189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
671964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
6720ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
6721ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool
6722668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
6723ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
6724ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    if (ArchVersion() >= ARMv5T)
6725668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        return BXWritePC(context, addr);
6726ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    else
6727ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        return BranchWritePC((const Context)context, addr);
6728ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
6729ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
673026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
673126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool
6732668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
673326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{
673426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
6735668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        return BXWritePC(context, addr);
673626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    else
673726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        return BranchWritePC((const Context)context, addr);
673826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen}
673926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
6740ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode
6741ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet ()
6742ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
6743ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return m_inst_mode;
6744ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
6745ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
6746ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Set the 'T' bit of our CPSR.  The m_inst_mode gets updated when the next
6747558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed.  This function has a side effect of updating
6748558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary.
6749ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool
6750ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
6751ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
6752558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen    m_new_inst_cpsr = m_inst_cpsr;
6753ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    switch (arm_or_thumb)
6754ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    {
6755ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    default:
6756ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        return false;
6757ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    eModeARM:
6758ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        // Clear the T bit.
6759558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        m_new_inst_cpsr &= ~MASK_CPSR_T;
6760ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        break;
6761ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    eModeThumb:
6762ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        // Set the T bit.
6763558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        m_new_inst_cpsr |= MASK_CPSR_T;
6764ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        break;
6765ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    }
6766ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return true;
6767ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
6768ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
6769ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for
6770ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
6771ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
6772ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool
6773ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport()
6774ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{
6775ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    return (ArchVersion() >= ARMv7);
6776ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen}
6777ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
6778bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information
6779bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions.  This status
6780bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions.
6781bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult
6782bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
6783bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{
6784bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint32_t result;
6785bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint8_t carry_out;
6786bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint8_t overflow;
6787bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
6788bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint64_t unsigned_sum = x + y + carry_in;
6789bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
6790bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
6791bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    result = UnsignedBits(unsigned_sum, 31, 0);
6792bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    carry_out = (result == unsigned_sum ? 0 : 1);
6793bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    overflow = ((int32_t)result == signed_sum ? 0 : 1);
6794bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
6795bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    AddWithCarryResult res = { result, carry_out, overflow };
6796bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    return res;
6797bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen}
6798bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
6799157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenuint32_t
6800e39f22d1a369866808b8739c3cec15063d806833Johnny ChenEmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
6801157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{
6802e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t reg_kind, reg_num;
6803e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    switch (num)
6804157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    {
6805e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    case SP_REG:
6806e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_kind = eRegisterKindGeneric;
6807e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_num  = LLDB_REGNUM_GENERIC_SP;
6808e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
6809e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    case LR_REG:
6810e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_kind = eRegisterKindGeneric;
6811e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_num  = LLDB_REGNUM_GENERIC_RA;
6812e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
6813e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    case PC_REG:
6814e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_kind = eRegisterKindGeneric;
6815e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_num  = LLDB_REGNUM_GENERIC_PC;
6816e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
6817e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    default:
6818e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        if (0 <= num && num < SP_REG)
6819e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        {
6820e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            reg_kind = eRegisterKindDWARF;
6821e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            reg_num  = dwarf_r0 + num;
6822e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        }
6823157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        else
6824e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        {
6825e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            assert(0 && "Invalid register number");
6826e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            *success = false;
6827e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            return ~0u;
6828e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        }
6829e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
6830e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    }
6831e39f22d1a369866808b8739c3cec15063d806833Johnny Chen
6832e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // Read our register.
6833e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
6834e39f22d1a369866808b8739c3cec15063d806833Johnny Chen
6835e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // When executing an ARM instruction , PC reads as the address of the current
6836e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // instruction plus 8.
6837e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // When executing a Thumb instruction , PC reads as the address of the current
6838e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // instruction plus 4.
6839e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    if (num == 15)
6840e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    {
6841e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        if (CurrentInstrSet() == eModeARM)
6842157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            val += 8;
6843e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        else
6844e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            val += 4;
6845157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    }
6846157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
6847157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    return val;
6848157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen}
6849157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
6850ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the
6851ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result.
6852ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
6853ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the
6854ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual:
6855ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
6856ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then         // Can only occur for encoding A1
6857ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     ALUWritePC(result); // setflags is always FALSE here
6858ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else
6859ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     R[d] = result;
6860ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     if setflags then
6861ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.N = result<31>;
6862ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.Z = IsZeroBit(result);
6863ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.C = carry;
6864ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         // APSR.V unchanged
6865ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
6866ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which
6867ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u.
6868ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool
686910530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
687010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t result,
687110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t Rd,
687210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  bool setflags,
687310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t carry,
687410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t overflow)
6875ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{
6876ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    if (Rd == 15)
6877ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    {
6878ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (!ALUWritePC (context, result))
6879ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
6880ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    }
6881ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    else
6882ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    {
6883ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result))
6884ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
6885ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (setflags)
688610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen            return WriteFlags (context, result, carry, overflow);
688710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    }
688810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    return true;
688910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen}
689010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
689110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the
689210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual:
689310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen//
689410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>;
689510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result);
689610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry;
689710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow
689810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen//
689910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means
690010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags.
690110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool
690210530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context,
690310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t result,
690410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t carry,
690510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t overflow)
690610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{
690710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    m_new_inst_cpsr = m_inst_cpsr;
690810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N));
690910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0);
691010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (carry != ~0u)
691110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        SetBit32(m_new_inst_cpsr, CPSR_C, carry);
691210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (overflow != ~0u)
691310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        SetBit32(m_new_inst_cpsr, CPSR_V, overflow);
691410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (m_new_inst_cpsr != m_inst_cpsr)
691510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    {
691610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
691710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen            return false;
6918ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    }
6919ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    return true;
6920ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen}
6921ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
692264c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
692364c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::EvaluateInstruction ()
692464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
6925c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    // Advance the ITSTATE bits to their values for the next instruction.
6926c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (m_inst_mode == eModeThumb && m_it_session.InITBlock())
6927c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        m_it_session.ITAdvance();
6928c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
692964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return false;
693064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
6931