EmulateInstructionARM.cpp revision 9f687729f0a2fff5dde65ce789c3a02e84c2ffcc
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
260e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
270e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
280e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// ITSession implementation
290e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
300e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
310e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen
32930704795c783e5bf1768a43da6f957108b40873Johnny Chen// A8.6.50
33930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
34930704795c783e5bf1768a43da6f957108b40873Johnny Chenstatic unsigned short CountITSize(unsigned ITMask) {
35930704795c783e5bf1768a43da6f957108b40873Johnny Chen    // First count the trailing zeros of the IT mask.
36930704795c783e5bf1768a43da6f957108b40873Johnny Chen    unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
37930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (TZ > 3)
38930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
39930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT Mask '0000'\n");
40930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return 0;
41930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
42930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return (4 - TZ);
43930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
44930704795c783e5bf1768a43da6f957108b40873Johnny Chen
45930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Init ITState.  Note that at least one bit is always 1 in mask.
46930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InitIT(unsigned short bits7_0)
47930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
48930704795c783e5bf1768a43da6f957108b40873Johnny Chen    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
49930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (ITCounter == 0)
50930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
51930704795c783e5bf1768a43da6f957108b40873Johnny Chen
52930704795c783e5bf1768a43da6f957108b40873Johnny Chen    // A8.6.50 IT
53930704795c783e5bf1768a43da6f957108b40873Johnny Chen    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
54930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (FirstCond == 0xF)
55930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
56930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT FirstCond '1111'\n");
57930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
58930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
59930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (FirstCond == 0xE && ITCounter != 1)
60930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
61930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
62930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
63930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
64930704795c783e5bf1768a43da6f957108b40873Johnny Chen
65930704795c783e5bf1768a43da6f957108b40873Johnny Chen    ITState = bits7_0;
66930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return true;
67930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
68930704795c783e5bf1768a43da6f957108b40873Johnny Chen
69930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Update ITState if necessary.
70930704795c783e5bf1768a43da6f957108b40873Johnny Chenvoid ITSession::ITAdvance()
71930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
72930704795c783e5bf1768a43da6f957108b40873Johnny Chen    assert(ITCounter);
73930704795c783e5bf1768a43da6f957108b40873Johnny Chen    --ITCounter;
74930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (ITCounter == 0)
75930704795c783e5bf1768a43da6f957108b40873Johnny Chen        ITState = 0;
76930704795c783e5bf1768a43da6f957108b40873Johnny Chen    else
77930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
78930704795c783e5bf1768a43da6f957108b40873Johnny Chen        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
79930704795c783e5bf1768a43da6f957108b40873Johnny Chen        SetBits32(ITState, 4, 0, NewITState4_0);
80930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
81930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
82930704795c783e5bf1768a43da6f957108b40873Johnny Chen
83930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Return true if we're inside an IT Block.
84930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InITBlock()
85930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
86930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return ITCounter != 0;
87930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
88930704795c783e5bf1768a43da6f957108b40873Johnny Chen
89c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// Return true if we're the last instruction inside an IT Block.
90c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool ITSession::LastInITBlock()
91c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{
92c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    return ITCounter == 1;
93c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen}
94c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
95930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Get condition bits for the current thumb instruction.
96930704795c783e5bf1768a43da6f957108b40873Johnny Chenuint32_t ITSession::GetCond()
97930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
98c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (InITBlock())
99c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return Bits32(ITState, 7, 4);
100c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    else
101c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return COND_AL;
102930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
103930704795c783e5bf1768a43da6f957108b40873Johnny Chen
10464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// ARM constants used during decoding
10564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define REG_RD          0
10664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define LDM_REGLIST     1
10764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REG          15
10864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REGLIST_BIT  0x8000
10964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
110251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv4     (1u << 0)
11164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv4T    (1u << 1)
11264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5T    (1u << 2)
11364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TE   (1u << 3)
11464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TEJ  (1u << 4)
115251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv6     (1u << 5)
11664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6K    (1u << 6)
11764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6T2   (1u << 7)
118251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv7     (1u << 8)
11960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen#define ARMv8     (1u << 9)
12064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMvAll   (0xffffffffu)
12164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
1239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
1249b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
1252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
1260e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
1270e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
1280e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation
1290e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
1300e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
1310e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen
1322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid
1332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize ()
1347dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{
1352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1367dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen
1372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid
1382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate ()
13964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
1402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
142fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
143fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool
144fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
145fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{
1469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
1479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
1489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
149fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
150fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    uint32_t random_data = rand ();
151fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    const uint32_t addr_byte_size = GetAddressByteSize();
152fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
153cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice    if (!MemAWrite (context, address, random_data, addr_byte_size))
154fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        return false;
155fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
156fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    return true;
157fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice}
158fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
159713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
160713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool
161713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n)
162713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{
1639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
1649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
1659bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
166713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
16762ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen    bool success;
168713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
169713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
170713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!success)
171713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
172713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
173713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
174713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
175713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
176713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    return true;
177713c2665a27096b68f3f8956222375354f1292f8Caroline Tice}
178713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
17908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to
18008c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates
18108c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data.
1822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
1839f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulatePUSH (ARMEncoding encoding)
18464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
18564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0
18664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    // ARM pseudo code...
18764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (ConditionPassed())
18864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
18964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        EncodingSpecificOperations();
19064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        NullCheckIfThumbEE(13);
19164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        address = SP - 4*BitCount(registers);
19264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
19364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        for (i = 0 to 14)
19464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
19564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (registers<i> == ’1’)
19664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
19764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
19864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    MemA[address,4] = bits(32) UNKNOWN;
19964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                else
20064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    MemA[address,4] = R[i];
20164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                address = address + 4;
20264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
20364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
20464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
20564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (registers<15> == ’1’) // Only possible for encoding A1 or A2
20664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            MemA[address,4] = PCStoreValue();
20764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
20864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        SP = SP - 4*BitCount(registers);
20964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
21064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif
21164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
21264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool success = false;
2132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
21464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (!success)
21564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
21664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
21864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
2192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
2202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
22164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (!success)
22264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            return false;
2233c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        uint32_t registers = 0;
22491d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        uint32_t Rt; // the source register
2253c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        switch (encoding) {
226aedde1c6a33b123031499800f56954adc86058f5Johnny Chen        case eEncodingT1:
227108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 7, 0);
228aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            // The M bit represents LR.
229bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (Bit32(opcode, 8))
230ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                registers |= (1u << 14);
231aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            // if BitCount(registers) < 1 then UNPREDICTABLE;
232aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            if (BitCount(registers) < 1)
233aedde1c6a33b123031499800f56954adc86058f5Johnny Chen                return false;
234aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            break;
2357dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen        case eEncodingT2:
2367dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // Ignore bits 15 & 13.
237108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 15, 0) & ~0xa000;
2387dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if BitCount(registers) < 2 then UNPREDICTABLE;
2397dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            if (BitCount(registers) < 2)
2407dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen                return false;
2417dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            break;
2427dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen        case eEncodingT3:
243108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
2447dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if BadReg(t) then UNPREDICTABLE;
24591d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            if (BadReg(Rt))
2467dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen                return false;
24791d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            registers = (1u << Rt);
2487dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            break;
2493c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        case eEncodingA1:
250108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 15, 0);
251a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // Instead of return false, let's handle the following case as well,
252a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // which amounts to pushing one reg onto the full descending stacks.
253a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
2543c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen            break;
2553c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        case eEncodingA2:
256108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
2577dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if t == 13 then UNPREDICTABLE;
25891d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            if (Rt == dwarf_sp)
2593c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen                return false;
26091d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            registers = (1u << Rt);
2613c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen            break;
262ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        default:
263ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
2643c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        }
265ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t sp_offset = addr_byte_size * BitCount (registers);
26664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        addr_t addr = sp - sp_offset;
26764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        uint32_t i;
26864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
2709bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPushRegisterOnStack;
2719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
2729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
27364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        for (i=0; i<15; ++i)
27464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
2757c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen            if (BitIsSet (registers, i))
27664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
2779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                dwarf_reg.num = dwarf_r0 + i;
2789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
2799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
28064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if (!success)
28164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    return false;
282cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
28364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    return false;
28464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                addr += addr_byte_size;
28564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
28664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
28764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
2887c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen        if (BitIsSet (registers, 15))
28964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
2909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_pc;
2919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
2922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
29364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (!success)
29464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                return false;
295cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, addr, pc + 8, addr_byte_size))
29664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                return false;
29764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
29864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
29964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        context.type = EmulateInstruction::eContextAdjustStackPointer;
3009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
30164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
3022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
30364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            return false;
30464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
30564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return true;
30664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
30764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
308ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from
309ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates
310ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data.
3112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
3129f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulatePOP (ARMEncoding encoding)
313ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{
314ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0
315ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    // ARM pseudo code...
316ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    if (ConditionPassed())
317ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    {
318ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
319ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        address = SP;
320ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        for i = 0 to 14
321ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if registers<i> == ‘1then
322ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
323ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if registers<15> == ‘1then
324ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if UnalignedAllowed then
325ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                LoadWritePC(MemU[address,4]);
326ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            else
327ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                LoadWritePC(MemA[address,4]);
328ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers);
329ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if registers<13> == ‘1then SP = bits(32) UNKNOWN;
330ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    }
331ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif
332ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
333ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    bool success = false;
3342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
335ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    if (!success)
336ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        return false;
337ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
3382b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
339ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    {
3402b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
3412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
342ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if (!success)
343ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
344ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t registers = 0;
345ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t Rt; // the destination register
346ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        switch (encoding) {
347ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT1:
348ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 7, 0);
349ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // The P bit represents PC.
350bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (Bit32(opcode, 8))
351ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                registers |= (1u << 15);
352ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(registers) < 1 then UNPREDICTABLE;
353ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (BitCount(registers) < 1)
354ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
355ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
356ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT2:
357ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // Ignore bit 13.
358ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 15, 0) & ~0x2000;
359ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
360bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
361ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
362098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
363098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
364098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                return false;
365ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
366ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT3:
367ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            Rt = Bits32(opcode, 15, 12);
368ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
369098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 13)
370098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                return false;
371098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 15 && InITBlock() && !LastInITBlock())
372ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
373ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = (1u << Rt);
374ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
375ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingA1:
376ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 15, 0);
377ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // Instead of return false, let's handle the following case as well,
378ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // which amounts to popping one reg from the full descending stacks.
379ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
380ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
381ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE;
382098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
383ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
384ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
385ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingA2:
386ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            Rt = Bits32(opcode, 15, 12);
387ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if t == 13 then UNPREDICTABLE;
388ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (Rt == dwarf_sp)
389ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
390ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = (1u << Rt);
391ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
392ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        default:
393ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
394ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
395ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        addr_t sp_offset = addr_byte_size * BitCount (registers);
396ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        addr_t addr = sp;
397ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t i, data;
398ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
3999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
4009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPopRegisterOffStack;
4019bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
4029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
403ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        for (i=0; i<15; ++i)
404ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        {
4057c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen            if (BitIsSet (registers, i))
406ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            {
4079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                dwarf_reg.num = dwarf_r0 + i;
4089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
409cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                data = MemARead(context, addr, 4, 0, &success);
410ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                if (!success)
411ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                    return false;
4129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
413ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                    return false;
414ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                addr += addr_byte_size;
415ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            }
416ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
417ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4187c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen        if (BitIsSet (registers, 15))
419ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        {
4209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_pc;
4219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
422cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            data = MemARead(context, addr, 4, 0, &success);
423ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (!success)
424ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
425f3eaacfc02d0a98d3bac1eaef74ad5c1c66ccfdcJohnny Chen            // In ARMv5T and above, this is an interworking branch.
426668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
427ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
428ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            addr += addr_byte_size;
429ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
430ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
431ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
4329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
433ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
435ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
436ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    }
437ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    return true;
438ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen}
439ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
4405b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// Set r7 or ip to point to saved value residing within the stack.
441bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen// ADD (SP plus immediate)
4422b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
4439f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateADDRdSPImm (ARMEncoding encoding)
444bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{
445bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0
446bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    // ARM pseudo code...
447bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    if (ConditionPassed())
448bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    {
449bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        EncodingSpecificOperations();
450bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
451bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        if d == 15 then
452bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
453bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        else
454bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            R[d] = result;
455bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            if setflags then
456bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.N = result<31>;
457bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.Z = IsZeroBit(result);
458bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.C = carry;
459bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.V = overflow;
460bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    }
461bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#endif
462bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
463bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    bool success = false;
4642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
465bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    if (!success)
466bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        return false;
467bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
4682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
469bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    {
4702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
471bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        if (!success)
472bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
473bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        uint32_t Rd; // the destination register
474bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        uint32_t imm32;
475bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        switch (encoding) {
476bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        case eEncodingT1:
477bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            Rd = 7;
478bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
479bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            break;
480bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        case eEncodingA1:
481bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            Rd = Bits32(opcode, 15, 12);
482bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
483bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            break;
484bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        default:
485bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
486bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        }
487bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        addr_t sp_offset = imm32;
488bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        addr_t addr = sp + sp_offset; // a pointer to the stack area
489bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
4909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
4919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
4929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register sp_reg;
4939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
4949bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (sp_reg, sp_offset);
495bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
4962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
497bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
498bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    }
499bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    return true;
500bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen}
501bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
5022ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer.
5032ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register)
5042b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
5059f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdSP (ARMEncoding encoding)
5062ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{
5072ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0
5082ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    // ARM pseudo code...
5092ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    if (ConditionPassed())
5102ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    {
5112ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        EncodingSpecificOperations();
5122ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        result = R[m];
5132ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        if d == 15 then
5142ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
5152ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        else
5162ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            R[d] = result;
5172ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            if setflags then
5182ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                APSR.N = result<31>;
5192ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                APSR.Z = IsZeroBit(result);
5202ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                // APSR.C unchanged
5212ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                // APSR.V unchanged
5222ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    }
5232ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif
5242ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5252ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    bool success = false;
5262b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    //const uint32_t opcode = OpcodeAsUnsigned (&success);
5271c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    //if (!success)
5281c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    //    return false;
5292ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5302b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
5312ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    {
5322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
5332ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        if (!success)
5342ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
5352ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        uint32_t Rd; // the destination register
5362ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        switch (encoding) {
5372ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        case eEncodingT1:
5382ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            Rd = 7;
5392ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            break;
5402ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        case eEncodingA1:
5412ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            Rd = 12;
5422ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            break;
5432ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        default:
5442ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
5452ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        }
5469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
5479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
5489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
5499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register sp_reg;
5509bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
5519bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (sp_reg, 0);
5522ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5532b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
5542ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
5552ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    }
5562ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    return true;
5572ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen}
5582ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
5591c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7).
5601c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register)
5612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
5629f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVLowHigh (ARMEncoding encoding)
5631c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{
5649f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen    return EmulateMOVRdRm (encoding);
565338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen}
566338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen
567338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register.
568338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register)
569338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool
5709f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdRm (ARMEncoding encoding)
571338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{
5721c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0
5731c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    // ARM pseudo code...
5741c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    if (ConditionPassed())
5751c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    {
5761c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        EncodingSpecificOperations();
5771c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        result = R[m];
5781c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        if d == 15 then
5791c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
5801c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        else
5811c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            R[d] = result;
5821c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            if setflags then
5831c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                APSR.N = result<31>;
5841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                APSR.Z = IsZeroBit(result);
5851c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                // APSR.C unchanged
5861c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                // APSR.V unchanged
5871c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    }
5881c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif
5891c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
5901c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    bool success = false;
5912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
5921c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    if (!success)
5931c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        return false;
5941c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
5952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
5961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    {
5971c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        uint32_t Rm; // the source register
5981c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        uint32_t Rd; // the destination register
599338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        bool setflags;
6001c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        switch (encoding) {
6011c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        case eEncodingT1:
6021c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            Rm = Bits32(opcode, 6, 3);
603bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1);
604338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            setflags = false;
605338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            break;
606338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        case eEncodingT2:
607338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            Rm = Bits32(opcode, 5, 3);
608338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            Rd = Bits32(opcode, 2, 1);
609338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            setflags = true;
6101c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            break;
6111c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        default:
6121c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            return false;
6131c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        }
614ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        uint32_t result = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
6151c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        if (!success)
6161c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            return false;
6171c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
6181c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        // The context specifies that Rm is to be moved into Rd.
6199bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
6209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
6219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
6229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
6239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, 0);
624ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
62510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
626ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
6271c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    }
6281c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    return true;
6291c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen}
6301c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
631357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register.  It
632357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value.
633357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate)
634357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool
6359f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMOVRdImm (ARMEncoding encoding)
636357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{
637357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0
638357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    // ARM pseudo code...
639357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (ConditionPassed())
640357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    {
641357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        EncodingSpecificOperations();
642357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        result = imm32;
643357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
644357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
645357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        else
646357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            R[d] = result;
647357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            if setflags then
648357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.N = result<31>;
649357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.Z = IsZeroBit(result);
650357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.C = carry;
651357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                // APSR.V unchanged
652357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    }
653357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif
654357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    bool success = false;
655357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
656357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (!success)
657357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        return false;
658357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
659357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (ConditionPassed())
660357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    {
661357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t Rd; // the destination register
662357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm12; // some intermediate result
663357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm32; // the immediate value to be written to Rd
664357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
665357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        bool setflags;
666357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        switch (encoding) {
667357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        case eEncodingT1:
668357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            Rd = Bits32(opcode, 11, 8);
669357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            setflags = !InITBlock();
670357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
671357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            carry = Bit32(m_inst_cpsr, CPSR_C);
672357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            break;
673357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        case eEncodingT2:
674357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            Rd = Bits32(opcode, 15, 12);
675357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            setflags = BitIsSet(opcode, 20);
676357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0);
677357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry);
6789798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen            if (BadReg(Rd))
6799798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen                return false;
680357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            break;
681357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        default:
682357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            return false;
683357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        }
684357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t result = imm32;
685357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
686357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        // The context specifies that an immediate is to be moved into Rd.
6879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
6889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
6899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
690ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
69110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
692ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
693357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    }
694357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    return true;
695357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen}
696357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
69728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
69828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen// the destination register.  It can optionally update the condition flags based
69928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen// on the value.
70028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen// MVN (immediate)
70128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool
7029f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateMVNRdImm (ARMEncoding encoding)
70328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{
70428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0
70528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    // ARM pseudo code...
70628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    if (ConditionPassed())
70728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    {
70828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        EncodingSpecificOperations();
70928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        result = NOT(imm32);
71028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
71128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
71228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        else
71328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            R[d] = result;
71428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            if setflags then
71528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.N = result<31>;
71628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.Z = IsZeroBit(result);
71728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.C = carry;
71828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                // APSR.V unchanged
71928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    }
72028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif
72133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    bool success = false;
72233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
72333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    if (!success)
72433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        return false;
72533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen
72633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    if (ConditionPassed())
72733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    {
72833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        uint32_t Rd; // the destination register
729357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm12; // the first operand to ThumbExpandImm_C or ARMExpandImm_C
730357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
731357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
73233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        bool setflags;
73333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        switch (encoding) {
73433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        case eEncodingT1:
73533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            Rd = Bits32(opcode, 11, 8);
73633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            setflags = BitIsSet(opcode, 20);
737357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0);
73833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry);
73933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            break;
74033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        case eEncodingA1:
74133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            Rd = Bits32(opcode, 15, 12);
74233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            setflags = BitIsSet(opcode, 20);
743357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            imm12 = Bits32(opcode, 11, 0);
74433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            imm32 = ARMExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry);
74533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            break;
74633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        default:
74733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            return false;
74833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        }
74933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        uint32_t result = ~imm32;
75033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen
75133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
7529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
7539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
7549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
755ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
75610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
757ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
75833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    }
75933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    return true;
76028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen}
76128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen
762788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register).
763788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal)
7642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
765c9de910d61f0471d18fced716fc10681ef432010Johnny ChenEmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding)
766788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{
767788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0
768788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    // ARM pseudo code...
769788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    if (ConditionPassed())
770788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    {
771788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
772788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        base = Align(PC,4);
773788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        address = if add then (base + imm32) else (base - imm32);
774788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        data = MemU[address,4];
775788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if t == 15 then
776788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE;
777788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        elsif UnalignedSupport() || address<1:0> = ‘00’ then
778788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            R[t] = data;
779788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        else // Can only apply before ARMv7
780788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            if CurrentInstrSet() == InstrSet_ARM then
781788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen                R[t] = ROR(data, 8*UInt(address<1:0>));
782788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            else
783788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen                R[t] = bits(32) UNKNOWN;
784788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    }
785788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif
786788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
787788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    bool success = false;
7882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
789788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    if (!success)
790788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        return false;
791788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
7922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
793788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    {
7942b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
795788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if (!success)
796788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
797809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen
798809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen        // PC relative immediate load context
7999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
8009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
8019bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register pc_reg;
8029bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
8039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (pc_reg, 0);
8049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
805c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        uint32_t Rt;    // the destination register
806788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        uint32_t imm32; // immediate offset from the PC
807c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        bool add;       // +imm32 or -imm32?
808c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        addr_t base;    // the base address
809c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        addr_t address; // the PC relative address
810788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        uint32_t data;  // the literal data value from the PC relative load
811788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        switch (encoding) {
812788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        case eEncodingT1:
813c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            Rt = Bits32(opcode, 10, 8);
814788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
815c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            add = true;
816c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            base = Align(pc + 4, 4);
8179bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 4 + imm32);
818c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            break;
819c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        case eEncodingT2:
820c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            Rt = Bits32(opcode, 15, 12);
821c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
822c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            add = BitIsSet(opcode, 23);
823098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 15 && InITBlock() && !LastInITBlock())
824c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
825c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            base = Align(pc + 4, 4);
8269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 4 + imm32);
827788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            break;
828788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        default:
829788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
830788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        }
831c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
832c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (add)
833c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            address = base + imm32;
834c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else
835c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            address = base - imm32;
836cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        data = MemURead(context, address, 4, 0, &success);
837788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if (!success)
838809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen            return false;
839c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
840c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (Rt == 15)
841c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        {
842c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            if (Bits32(address, 1, 0) == 0)
843c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            {
844c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                // In ARMv5T and above, this is an interworking branch.
845668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen                if (!LoadWritePC(context, data))
846c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                    return false;
847c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            }
848c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            else
849c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
850c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        }
851c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
852c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        {
853c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
854c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
855c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        }
856c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else // We don't handle ARM for now.
857c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            return false;
858c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
859c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
860788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
861788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    }
862788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    return true;
863788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen}
864788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
8655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP.
866fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate)
8672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
8682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding)
869fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{
870fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0
871fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    // ARM pseudo code...
872fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    if (ConditionPassed())
873fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    {
874fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        EncodingSpecificOperations();
875fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’);
876fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        if d == 15 then // Can only occur for ARM encoding
877fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
878fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        else
879fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            R[d] = result;
880fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            if setflags then
881fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.N = result<31>;
882fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.Z = IsZeroBit(result);
883fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.C = carry;
884fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.V = overflow;
885fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    }
886fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif
887fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
888fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    bool success = false;
8892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
890fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    if (!success)
891fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        return false;
892fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
8932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
894fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    {
8952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
896fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        if (!success)
897fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
898fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        uint32_t imm32; // the immediate operand
899fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        switch (encoding) {
900fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        case eEncodingT2:
901fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
902fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            break;
903fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        default:
904fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
905fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        }
906fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        addr_t sp_offset = imm32;
907fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
908fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
9099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
9109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
9119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
912fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
9132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
914fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
915fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    }
916fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    return true;
917fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen}
918fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
919fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP.
9205b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register)
9212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
9222b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding)
9235b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{
9245b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0
9255b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    // ARM pseudo code...
9265b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    if (ConditionPassed())
9275b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    {
9285b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        EncodingSpecificOperations();
9295b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9305b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’);
9315b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if d == 15 then
9325b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
9335b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        else
9345b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            R[d] = result;
9355b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            if setflags then
9365b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.N = result<31>;
9375b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.Z = IsZeroBit(result);
9385b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.C = carry;
9395b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.V = overflow;
9405b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    }
9415b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif
9425b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
9435b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    bool success = false;
9442b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
9455b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    if (!success)
9465b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        return false;
9475b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
9482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
9495b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    {
9502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
9515b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if (!success)
9525b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
9535b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        uint32_t Rm; // the second operand
9545b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        switch (encoding) {
9555b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        case eEncodingT2:
9565b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            Rm = Bits32(opcode, 6, 3);
9575b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            break;
9585b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        default:
9595b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
9605b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        }
9612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
9625b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if (!success)
9635b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
9645b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
9655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
9665b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
9679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
9689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
9699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (reg_value);
9705b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
9712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
9725b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
9735b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    }
9745b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    return true;
9755b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen}
9765b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
9779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
9789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or
9799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM.
9809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate)
9819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool
9829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny ChenEmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding)
9839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{
9849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0
9859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    // ARM pseudo code...
9869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
9879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
9889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        EncodingSpecificOperations();
9899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if CurrentInstrSet() == InstrSet_ARM then
9909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = PC - 4;
9919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
9929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = PC<31:1> : '1';
9939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if targetInstrSet == InstrSet_ARM then
9949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            targetAddress = Align(PC,4) + imm32;
9959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
9969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            targetAddress = PC + imm32;
9979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        SelectInstrSet(targetInstrSet);
9989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        BranchWritePC(targetAddress);
9999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
10009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif
10019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
10029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    bool success = false;
10039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
10049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (!success)
10059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        return false;
10069b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
10079b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
10089b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
10099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
10109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
10119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
10129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!success)
10139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
101453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t lr; // next instruction address
101553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t target; // target address
10169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        int32_t imm32; // PC-relative offset
10179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        switch (encoding) {
1018d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        case eEncodingT1:
1019d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            {
1020d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            lr = (pc + 4) | 1u; // return address
1021bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
1022d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t imm10 = Bits32(opcode, 25, 16);
1023bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1024bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
1025d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
1026d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t I1 = !(J1 ^ S);
1027d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t I2 = !(J2 ^ S);
102853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1029d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1030d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            target = pc + 4 + imm32;
10319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1032098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1033ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
1034d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            break;
1035d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            }
10369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingT2:
10379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            {
10389b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            lr = (pc + 4) | 1u; // return address
1039bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
10409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t imm10H = Bits32(opcode, 25, 16);
1041bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1042bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
10439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t imm10L = Bits32(opcode, 10, 1);
10449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t I1 = !(J1 ^ S);
10459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t I2 = !(J2 ^ S);
104653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
10479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1048d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            target = Align(pc + 4, 4) + imm32;
10499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1050098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1051ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
10529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
10539b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            }
1054c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen        case eEncodingA1:
1055c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            lr = pc + 4; // return address
1056c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1057d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            target = Align(pc + 8, 4) + imm32;
10589bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1059c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            break;
10609b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingA2:
10619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            lr = pc + 4; // return address
10629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
10639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            target = pc + 8 + imm32;
10649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
10659b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
10669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        default:
10679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
10689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        }
10699b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
10709b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
10719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!BranchWritePC(context, target))
10729b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
10739b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
10749b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    return true;
10759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen}
10769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
10779b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and
10789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register.
10799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register)
10809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool
10819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny ChenEmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding)
10829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{
10839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0
10849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    // ARM pseudo code...
10859b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
10869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
10879b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        EncodingSpecificOperations();
10889b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        target = R[m];
10899b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if CurrentInstrSet() == InstrSet_ARM then
10909b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            next_instr_addr = PC - 4;
10919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = next_instr_addr;
10929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
10939b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            next_instr_addr = PC - 2;
10949b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = next_instr_addr<31:1> : ‘1’;
10959b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        BXWritePC(target);
10969b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
10979b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif
10989b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
10999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    bool success = false;
11009b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
11019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (!success)
11029b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        return false;
11039b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
11049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
11059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
11069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
11079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
11089b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
11099b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        addr_t lr; // next instruction address
11109b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!success)
11119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
11129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        uint32_t Rm; // the register with the target address
11139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        switch (encoding) {
11149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingT1:
11159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            lr = (pc + 2) | 1u; // return address
11169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            Rm = Bits32(opcode, 6, 3);
11179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            // if m == 15 then UNPREDICTABLE;
11189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            if (Rm == 15)
11199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen                return false;
1120098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1121ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
11229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
11239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingA1:
11249b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            lr = pc + 4; // return address
11259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            Rm = Bits32(opcode, 3, 0);
11269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            // if m == 15 then UNPREDICTABLE;
11279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            if (Rm == 15)
11289b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen                return false;
1129b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
11309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        default:
11319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
11329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        }
1133ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1134ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        if (!success)
1135ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
11369bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
11379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
11389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegister (dwarf_reg);
11399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
11409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
1141668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        if (!BXWritePC(context, target))
11429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
11439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
11449b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    return true;
11459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen}
11469b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
1147ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1148ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// BX
1149ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool
1150ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny ChenEmulateInstructionARM::EmulateBXRm (ARMEncoding encoding)
1151ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{
1152ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0
1153ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    // ARM pseudo code...
1154ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (ConditionPassed())
1155ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    {
1156ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        EncodingSpecificOperations();
1157ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        BXWritePC(R[m]);
1158ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    }
1159ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif
1160ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
1161ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    bool success = false;
1162ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1163ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (!success)
1164ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        return false;
1165ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
1166ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (ConditionPassed())
1167ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    {
11689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
11699bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1170ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        uint32_t Rm; // the register with the target address
1171ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        switch (encoding) {
1172ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        case eEncodingT1:
1173ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            Rm = Bits32(opcode, 6, 3);
1174098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1175ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
1176ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            break;
1177ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        case eEncodingA1:
1178ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            Rm = Bits32(opcode, 3, 0);
1179ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            break;
1180ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        default:
1181ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1182ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        }
1183ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
1184ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        if (!success)
1185ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
11869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
11879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
11889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1189668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetRegister (dwarf_reg);
1190668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        if (!BXWritePC(context, target))
1191ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1192ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    }
1193ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    return true;
1194ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen}
1195ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
11960d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset.
11970d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate)
11982b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
11992b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding)
12000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{
12010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0
12020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    // ARM pseudo code...
12030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (ConditionPassed())
12040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
12050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        EncodingSpecificOperations();
12060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
12070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if d == 15 then // Can only occur for ARM encoding
12080d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
12090d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        else
12100d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            R[d] = result;
12110d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            if setflags then
12120d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.N = result<31>;
12130d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.Z = IsZeroBit(result);
12140d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.C = carry;
12150d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.V = overflow;
12160d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
12170d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif
12180d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12190d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    bool success = false;
12202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
12210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (!success)
12220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        return false;
12230d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12242b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
12250d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
12262b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success);
12270d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if (!success)
12280d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
12290d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        uint32_t imm32;
12300d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        switch (encoding) {
12310d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        case eEncodingA1:
12320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
12330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            break;
12340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        default:
12350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
12360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        }
12370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t ip_offset = imm32;
12380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t addr = ip - ip_offset; // the adjusted ip value
12390d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
12419bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
12429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
12439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
12449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
12450d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
12470d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
12480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
12490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    return true;
12500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen}
12510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset.
12530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate)
12542b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
12552b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding)
12560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{
12570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0
12580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    // ARM pseudo code...
12590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (ConditionPassed())
12600d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
12610d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        EncodingSpecificOperations();
12620d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
12630d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if d == 15 then // Can only occur for ARM encoding
12640d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
12650d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        else
12660d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            R[d] = result;
12670d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            if setflags then
12680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.N = result<31>;
12690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.Z = IsZeroBit(result);
12700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.C = carry;
12710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.V = overflow;
12720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
12730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif
12740d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12750d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    bool success = false;
12762b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
12770d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (!success)
12780d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        return false;
12790d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
12810d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
12822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
12830d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if (!success)
12840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
12850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        uint32_t imm32;
12860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        switch (encoding) {
12870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        case eEncodingA1:
12880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
12890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            break;
12900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        default:
12910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
12920d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        }
12930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t sp_offset = imm32;
12940d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
12950d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
12969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
12979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
12989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
12999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
13009bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
13010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
13030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
13040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
13050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    return true;
13060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen}
13070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
13084c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen// A sub operation to adjust the SP -- allocate space for local storage.
13092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
13102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding)
13114c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{
13124c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0
13134c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    // ARM pseudo code...
13144c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    if (ConditionPassed())
13154c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    {
13164c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        EncodingSpecificOperations();
13174c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’);
13184c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        if d == 15 then // Can only occur for ARM encoding
1319799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
13204c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        else
13214c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            R[d] = result;
13224c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            if setflags then
13234c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.N = result<31>;
13244c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.Z = IsZeroBit(result);
13254c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.C = carry;
13264c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.V = overflow;
13274c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    }
13284c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif
13294c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
13304c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    bool success = false;
13312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
13324c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    if (!success)
13334c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        return false;
13344c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
13352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
13364c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    {
13372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
13384c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        if (!success)
13394c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
13404c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        uint32_t imm32;
13414c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        switch (encoding) {
1342e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen        case eEncodingT1:
1343e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen            imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
134460c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen        case eEncodingT2:
134560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
134660c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            break;
134760c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen        case eEncodingT3:
134860c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
134960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            break;
13504c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        case eEncodingA1:
135160c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
13524c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            break;
13534c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        default:
13544c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
13554c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        }
13564c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        addr_t sp_offset = imm32;
13574c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
13584c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
13599bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
13609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
13619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
13624c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
13632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
13644c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
13654c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    }
13664c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    return true;
13674c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen}
13684c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
136908c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP.
13702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
13712b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding)
1372ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{
1373ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0
1374ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    // ARM pseudo code...
1375ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    if (ConditionPassed())
1376ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    {
1377ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        EncodingSpecificOperations();
1378ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1379ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        address = if index then offset_addr else R[n];
1380ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1381ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        if wback then R[n] = offset_addr;
1382ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    }
1383ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif
1384ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
1385ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    bool success = false;
13862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
1387ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    if (!success)
1388ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        return false;
1389ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
13902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
1391ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    {
13922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
13932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1394ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        if (!success)
1395ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
139691d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        uint32_t Rt; // the source register
1397ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        uint32_t imm12;
1398ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        switch (encoding) {
1399ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        case eEncodingA1:
1400108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
1401108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            imm12 = Bits32(opcode, 11, 0);
1402ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            break;
1403ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        default:
1404ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
1405ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1406ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t sp_offset = imm12;
1407ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t addr = sp - sp_offset;
1408ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
14099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
14109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPushRegisterOnStack;
14119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
14129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
141391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        if (Rt != 15)
1414ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        {
14159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_r0 + Rt;
14169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
14179bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1418ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            if (!success)
1419ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1420cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1421ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1422ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1423ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        else
1424ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        {
14259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = dwarf_pc;
14269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
14272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1428ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            if (!success)
1429ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1430cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, addr, pc + 8, addr_byte_size))
1431ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1432ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1433ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
1434ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
14359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
1436ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
14372b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1438ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
1439ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    }
1440ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    return true;
1441ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen}
1442ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
144308c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack.
144408c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data.
14452b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
14462b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding)
1447799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{
1448799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0
1449799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    // ARM pseudo code...
1450799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    if (ConditionPassed())
1451799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    {
1452799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1453799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        address = SP - imm32;
1454799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        SP = SP - imm32;
1455799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        if single_regs then
1456799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            for r = 0 to regs-1
1457799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address,4] = S[d+r]; address = address+4;
1458799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        else
1459799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            for r = 0 to regs-1
1460799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                // Store as two word-aligned words in the correct order for current endianness.
1461799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1462799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1463799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                address = address+8;
1464799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    }
1465799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif
1466799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
1467799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    bool success = false;
14682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const uint32_t opcode = OpcodeAsUnsigned (&success);
1469799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    if (!success)
1470799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        return false;
1471799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
14722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    if (ConditionPassed())
1473799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    {
14742b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
14752b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1476799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        if (!success)
1477799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
1478799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        bool single_regs;
1479587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1480799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t imm32; // stack offset
1481799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t regs;  // number of registers
1482799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        switch (encoding) {
1483799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingT1:
1484799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingA1:
1485799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            single_regs = false;
1486bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1487799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1488799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // If UInt(imm8) is odd, see "FSTMX".
1489799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            regs = Bits32(opcode, 7, 0) / 2;
1490799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1491799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1492799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1493799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            break;
1494799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingT2:
1495799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingA2:
1496799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            single_regs = true;
1497bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1498799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1499799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            regs = Bits32(opcode, 7, 0);
1500799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1501799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1502799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1503799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            break;
1504799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        default:
1505799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
1506799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        }
1507799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1508799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1509799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        addr_t sp_offset = imm32;
1510799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        addr_t addr = sp - sp_offset;
1511799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t i;
1512799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
15139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
15149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPushRegisterOnStack;
15159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
15169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1517799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        for (i=d; i<regs; ++i)
1518799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        {
15199bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = start_reg + i;
15209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset ( dwarf_reg, addr - sp);
1521799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // uint64_t to accommodate 64-bit registers.
15229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1523799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (!success)
1524799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1525cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1526799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
1527799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            addr += reg_byte_size;
1528799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        }
1529799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
1530799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
15319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
1532799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
15332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1534799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
1535799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    }
1536799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    return true;
1537799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen}
1538799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
1539587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack.
1540587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data.
1541587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool
1542587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny ChenEmulateInstructionARM::EmulateVPOP (ARMEncoding encoding)
1543587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{
1544587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0
1545587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    // ARM pseudo code...
1546587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (ConditionPassed())
1547587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    {
1548587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1549587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        address = SP;
1550587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        SP = SP + imm32;
1551587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if single_regs then
1552587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            for r = 0 to regs-1
1553587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                S[d+r] = MemA[address,4]; address = address+4;
1554587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        else
1555587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            for r = 0 to regs-1
1556587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1557587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                // Combine the word-aligned words in the correct order for current endianness.
1558587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1559587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    }
1560587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif
1561587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1562587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    bool success = false;
1563587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1564587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (!success)
1565587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        return false;
1566587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1567587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (ConditionPassed())
1568587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    {
1569587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        const uint32_t addr_byte_size = GetAddressByteSize();
1570587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success);
1571587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if (!success)
1572587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
1573587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        bool single_regs;
1574587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1575587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t imm32; // stack offset
1576587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t regs;  // number of registers
1577587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        switch (encoding) {
1578587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingT1:
1579587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingA1:
1580587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            single_regs = false;
1581bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1582587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1583587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // If UInt(imm8) is odd, see "FLDMX".
1584587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            regs = Bits32(opcode, 7, 0) / 2;
1585587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1586587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1587587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
1588587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            break;
1589587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingT2:
1590587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingA2:
1591587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            single_regs = true;
1592bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1593587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1594587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            regs = Bits32(opcode, 7, 0);
1595587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1596587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
1597587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
1598587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            break;
1599587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        default:
1600587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
1601587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        }
1602587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1603587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1604587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        addr_t sp_offset = imm32;
1605587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        addr_t addr = sp;
1606587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t i;
1607587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint64_t data; // uint64_t to accomodate 64-bit registers.
1608587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
16099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
16109bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextPopRegisterOffStack;
16119bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
16129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1613587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        for (i=d; i<regs; ++i)
1614587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        {
16159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.num = start_reg + i;
16169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
1617cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            data = MemARead(context, addr, reg_byte_size, 0, &success);
1618587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (!success)
1619587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
16209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
1621587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
1622587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            addr += reg_byte_size;
1623587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        }
1624587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1625587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
16269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
1627587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1628587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
1629587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
1630587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    }
1631587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    return true;
1632587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen}
1633587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
1634b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI)
1635b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool
1636b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny ChenEmulateInstructionARM::EmulateSVC (ARMEncoding encoding)
1637b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{
1638b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0
1639b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    // ARM pseudo code...
1640b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (ConditionPassed())
1641b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    {
1642b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        EncodingSpecificOperations();
1643b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        CallSupervisor();
1644b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    }
1645b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif
1646b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
1647b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    bool success = false;
1648b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1649b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (!success)
1650b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        return false;
1651b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
1652b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (ConditionPassed())
1653b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    {
1654b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1655b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        addr_t lr; // next instruction address
1656b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        if (!success)
1657b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
1658b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        uint32_t imm32; // the immediate constant
1659b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        uint32_t mode;  // ARM or Thumb mode
1660b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        switch (encoding) {
1661b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        case eEncodingT1:
1662b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            lr = (pc + 2) | 1u; // return address
1663b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            imm32 = Bits32(opcode, 7, 0);
1664b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            mode = eModeThumb;
1665b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
1666b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        case eEncodingA1:
1667b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            lr = pc + 4; // return address
1668b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            imm32 = Bits32(opcode, 23, 0);
1669b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            mode = eModeARM;
1670b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
1671b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        default:
1672b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
1673b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        }
16749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
16759bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
16769bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextSupervisorCall;
16779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetModeAndImmediate (mode, imm32);
1678b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1679b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
1680b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    }
1681b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    return true;
1682b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen}
1683b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
1684c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional.
1685c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool
1686c315f860b343cf4a143f43c7d570d151989abb46Johnny ChenEmulateInstructionARM::EmulateIT (ARMEncoding encoding)
1687c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{
1688c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0
1689c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    // ARM pseudo code...
1690c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    EncodingSpecificOperations();
1691c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    ITSTATE.IT<7:0> = firstcond:mask;
1692c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif
1693c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
1694c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    bool success = false;
1695c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
1696c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (!success)
1697c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return false;
1698c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
1699c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    m_it_session.InitIT(Bits32(opcode, 7, 0));
1700c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    return true;
1701c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen}
1702c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
17033b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address.
17043b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool
17053b620b38cd170c20ea607585021ab2ab50286943Johnny ChenEmulateInstructionARM::EmulateB (ARMEncoding encoding)
17063b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{
17073b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0
17083b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    // ARM pseudo code...
17093b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    if (ConditionPassed())
17103b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    {
17113b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        EncodingSpecificOperations();
17123b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        BranchWritePC(PC + imm32);
17133b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    }
17143b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif
17153b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
17163b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    bool success = false;
17173b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
17183b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    if (!success)
17193b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        return false;
17203b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
17219ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (ConditionPassed())
17229ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
17239bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
17249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
17259ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
17269ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!success)
17279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
172853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t target; // target address
17299ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        int32_t imm32; // PC-relative offset
17309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        switch (encoding) {
17319ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT1:
17329ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
17339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
17349ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            target = pc + 4 + imm32;
17359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
17369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
17379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT2:
17389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
17399ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            target = pc + 4 + imm32;
17409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
17419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
17429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT3:
17439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
17449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            {
1745bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
17469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm6 = Bits32(opcode, 21, 16);
1747bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1748bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
17499ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
175053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
17519ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<21>(imm21);
17529ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            target = pc + 4 + imm32;
17539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
17549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
17559ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            }
17569ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT4:
17579ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            {
1758bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
17599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm10 = Bits32(opcode, 25, 16);
1760bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1761bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
17629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
17639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t I1 = !(J1 ^ S);
17649ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t I2 = !(J2 ^ S);
176553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
17669ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
17679ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            target = pc + 4 + imm32;
17689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
17699ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
17709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            }
17719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingA1:
17729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
17739ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            target = pc + 8 + imm32;
17749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
17759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
17769ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        default:
17779ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
17789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
17799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!BranchWritePC(context, target))
17809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
17819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
17829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    return true;
17833b620b38cd170c20ea607585021ab2ab50286943Johnny Chen}
17843b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
178553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
178653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
178753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ
178853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool
178953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny ChenEmulateInstructionARM::EmulateCB (ARMEncoding encoding)
179053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{
179153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0
179253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    // ARM pseudo code...
179353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    EncodingSpecificOperations();
179453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if nonzero ^ IsZero(R[n]) then
179553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        BranchWritePC(PC + imm32);
179653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif
179753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
179853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    bool success = false;
179953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
180053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
180153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
180253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
180353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    // Read the register value from the operand register Rn.
180453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success);
180553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
180653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
180753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
18089bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
18099bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
181053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
181153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
181253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
181353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
181453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    addr_t target;  // target address
181553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    uint32_t imm32; // PC-relative offset to branch forward
181653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    bool nonzero;
181753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    switch (encoding) {
181853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    case eEncodingT1:
1819bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
182053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        nonzero = BitIsSet(opcode, 11);
182153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        target = pc + 4 + imm32;
18229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
182353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        break;
182453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    default:
182553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
182653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    }
182753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (nonzero ^ (reg_val == 0))
182853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        if (!BranchWritePC(context, target))
182953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            return false;
183053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
183153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
183253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen}
183353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
183460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
183560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table.
183660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table.
183760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen//
183860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
183960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table.
184060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table.
184160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH
184260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool
184360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny ChenEmulateInstructionARM::EmulateTB (ARMEncoding encoding)
184460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{
184560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0
184660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // ARM pseudo code...
184760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
184860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if is_tbh then
184960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
185060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    else
185160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        halfwords = UInt(MemU[R[n]+R[m], 1]);
185260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    BranchWritePC(PC + 2*halfwords);
185360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif
185460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
185560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    bool success = false;
185660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
185760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
185860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
185960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
186060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
186160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
186260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    bool is_tbh;     // true if table branch halfword
186360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    switch (encoding) {
186460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    case eEncodingT1:
186560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rn = Bits32(opcode, 19, 16);
186660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rm = Bits32(opcode, 3, 0);
186760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        is_tbh = BitIsSet(opcode, 4);
186860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        if (Rn == 13 || BadReg(Rm))
186960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen            return false;
187060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        if (InITBlock() && !LastInITBlock())
187160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen            return false;
187260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        break;
187360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    default:
187460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
187560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    }
187660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
187760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // Read the address of the table from the operand register Rn.
187860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // The PC can be used, in which case the table immediately follows this instruction.
187960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t base =
188060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rn == 15 ? (ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success) + 4)
188160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen                 : ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
188260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
188360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
188460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
188560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // the table index
188660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t index = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
188760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
188860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
188960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
189060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // the offsetted table address
189160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    addr_t addr = base + (is_tbh ? index*2 : index);
189260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
189360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // PC-relative offset to branch forward
189460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    EmulateInstruction::Context context;
189560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.type = EmulateInstruction::eContextTableBranchReadMemory;
1896104c8b69863f229033d616245f56243ca51f1de9Johnny Chen    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
189760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
189860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
189960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
190060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
190160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
190260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
190360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
190460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // target address
190560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    addr_t target = pc + 4 + offset;
190660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
190760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
190860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
190960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!BranchWritePC(context, target))
191060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
191160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
191260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    return true;
191360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen}
191460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
1915d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result
1916d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result.
191726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool
19189f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateADDReg (ARMEncoding encoding)
191926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{
192026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0
192126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    // ARM pseudo code...
192226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if ConditionPassed() then
192326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        EncodingSpecificOperations();
192426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
192526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
192626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if d == 15 then
192726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
192826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        else
192926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            R[d] = result;
193026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            if setflags then
193126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.N = result<31>;
193226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.Z = IsZeroBit(result);
193326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.C = carry;
193426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.V = overflow;
193526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif
193626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
193726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    bool success = false;
193826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
193926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (!success)
194026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        return false;
194126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
194226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (ConditionPassed())
194326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    {
194426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        uint32_t Rd, Rn, Rm;
1945d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        ARM_ShifterType shift_t;
1946d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
1947ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        bool setflags;
194826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        switch (encoding)
194926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        {
1950d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        case eEncodingT1:
1951d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rd = Bits32(opcode, 2, 0);
1952d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rn = Bits32(opcode, 5, 3);
1953d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rm = Bits32(opcode, 8, 6);
1954d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            setflags = !InITBlock();
1955d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_t = SRType_LSL;
1956d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_n = 0;
195726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        case eEncodingT2:
1958bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
195926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            Rm = Bits32(opcode, 6, 3);
1960ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            setflags = false;
1961d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_t = SRType_LSL;
1962d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_n = 0;
196326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            if (Rn == 15 && Rm == 15)
196426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                return false;
1965d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            if (Rd == 15 && InITBlock() && !LastInITBlock())
1966d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                return false;
196726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            break;
196826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        default:
196926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
197026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        }
197126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
197226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        int32_t result, val1, val2;
197326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Read the first operand.
197426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (Rn == 15)
1975d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        {
197626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1977d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            if (encoding == eEncodingT1 || encoding == eEncodingT2)
1978d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                val1 += 4;
1979d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            else
1980d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                val1 += 8;
1981d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        }
198226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        else
198326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
198426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (!success)
198526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
198626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
198726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Read the second operand.
198826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (Rm == 15)
1989d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        {
199026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
1991d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            if (encoding == eEncodingT1 || encoding == eEncodingT2)
1992d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                val1 += 4;
1993d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            else
1994d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                val1 += 8;
1995d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        }
199626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        else
199726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
199826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (!success)
199926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
200026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
2001d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        val2 = Shift(val2, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C));
2002ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        AddWithCarryResult res = AddWithCarry(val1, val2, 0);
200326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        result = val1 + val2;
20049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
20059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
20069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
20079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
2008ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
200910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2010ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
201126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    }
201226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    return true;
201326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen}
201426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
2015e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen// CMP (immediate)
2016d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool
20179f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateCMPRnImm (ARMEncoding encoding)
2018d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{
2019d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0
2020d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    // ARM pseudo code...
2021d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if ConditionPassed() then
2022d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        EncodingSpecificOperations();
2023d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2024d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.N = result<31>;
2025d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.Z = IsZeroBit(result);
2026d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.C = carry;
2027d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.V = overflow;
2028d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif
2029d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2030d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    bool success = false;
2031d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
2032d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if (!success)
2033d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2034d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2035d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t Rn; // the first operand
2036d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t imm32; // the immediate value to be compared with
2037d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    switch (encoding) {
2038d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    case eEncodingT1:
2039d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        Rn = Bits32(opcode, 10, 8);
2040d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        imm32 = Bits32(opcode, 7, 0);
2041d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        break;
2042d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    default:
2043d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2044d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    }
2045d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    // Read the register value from the operand register Rn.
2046d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2047d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if (!success)
2048d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2049d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
205010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
205110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
20529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
20539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextImmediate;
20549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
205510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
205610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        return false;
205710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
2058d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    return true;
2059d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen}
2060d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2061e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen// CMP (register)
2062e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool
20639f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny ChenEmulateInstructionARM::EmulateCMPRnRm (ARMEncoding encoding)
2064e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{
2065e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0
2066e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // ARM pseudo code...
2067e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if ConditionPassed() then
2068e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        EncodingSpecificOperations();
2069e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2070e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2071e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.N = result<31>;
2072e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.Z = IsZeroBit(result);
2073e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.C = carry;
2074e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.V = overflow;
2075e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif
2076e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2077e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    bool success = false;
2078e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
2079e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2080e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2081e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2082e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t Rn; // the first operand
2083e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t Rm; // the second operand
2084e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    switch (encoding) {
2085e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    case eEncodingT1:
2086e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rn = Bits32(opcode, 2, 0);
2087e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rm = Bits32(opcode, 5, 3);
2088e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        break;
2089e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    case eEncodingT2:
2090e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2091e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rm = Bits32(opcode, 6, 3);
2092e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        if (Rn < 8 && Rm < 8)
2093e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen            return false;
2094e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        if (Rn == 15 || Rm == 15)
2095e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen            return false;
2096e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        break;
2097e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    default:
2098e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2099e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    }
2100e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // Read the register value from register Rn.
2101e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t reg_val1 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2102e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2103e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2104e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // Read the register value from register Rm.
2105e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // The register value is not being shifted since we don't handle ARM for now.
2106e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t reg_val2 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
2107e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2108e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2109e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
211010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    AddWithCarryResult res = AddWithCarry(reg_val1, ~reg_val2, 1);
211110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
21129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
21139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextImmediate;
21149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs();
211510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
211610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        return false;
211710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
2118e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    return true;
2119e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen}
2120e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
212182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
212282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register.  It can
212382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result.
212482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool
212582f16aa9f19678ffa20b92a8df926e933940d34dJohnny ChenEmulateInstructionARM::EmulateASRImm (ARMEncoding encoding)
212682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{
212782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0
212882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    // ARM pseudo code...
212982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if ConditionPassed() then
213082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        EncodingSpecificOperations();
213182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
213282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
213382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
213482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        else
213582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            R[d] = result;
213682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            if setflags then
213782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.N = result<31>;
213882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.Z = IsZeroBit(result);
213982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.C = carry;
214082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                // APSR.V unchanged
214182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif
214282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
214341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftImm(encoding, SRType_ASR);
214441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
214541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
214641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
214741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register.
214841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update
214941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result.
215041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
215141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateASRReg (ARMEncoding encoding)
215241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
215341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
215441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
215541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
215641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
215741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
215841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
215941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
216041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
216141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
216241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
216341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
216441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
216541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
216641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
216741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftReg(encoding, SRType_ASR);
216841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
216941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
217041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
217141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  It can optionally
217241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result.
217341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
217441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSLImm (ARMEncoding encoding)
217541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
217641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
217741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
217841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
217941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
218041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
218141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
218241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
218341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        else
218441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            R[d] = result;
218541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            if setflags then
218641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.N = result<31>;
218741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.Z = IsZeroBit(result);
218841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.C = carry;
218941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                // APSR.V unchanged
219041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
219141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
219241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftImm(encoding, SRType_LSL);
219341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
219441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
219541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits,
219641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  The variable number
219741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition
219841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result.
219941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
220041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSLReg (ARMEncoding encoding)
220141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
220241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
220341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
220441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
220541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
220641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
220741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
220841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
220941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
221041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
221141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
221241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
221341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
221441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
221541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
221641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftReg(encoding, SRType_LSL);
221741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
221841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
221941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
222041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  It can optionally
222141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result.
222241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
222341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSRImm (ARMEncoding encoding)
222441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
222541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
222641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
222741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
222841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
222941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
223041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
223141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
223241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        else
223341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            R[d] = result;
223441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            if setflags then
223541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.N = result<31>;
223641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.Z = IsZeroBit(result);
223741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.C = carry;
223841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                // APSR.V unchanged
223941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
224041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
224141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftImm(encoding, SRType_LSR);
224241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
224341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
224441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits,
224541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  The variable number
224641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition
224741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result.
224841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
224941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateLSRReg (ARMEncoding encoding)
225041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
225141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
225241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
225341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
225441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
225541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
225641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
225741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
225841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
225941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
226041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
226141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
226241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
226341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
226441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
226541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    return EmulateShiftReg(encoding, SRType_LSR);
226641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
226741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
2268eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2269eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2270eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result.
2271eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
2272eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRORImm (ARMEncoding encoding)
2273eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
2274eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
2275eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
2276eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
2277eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
2278eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2279eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
2280eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
2281eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        else
2282eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            R[d] = result;
2283eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            if setflags then
2284eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.N = result<31>;
2285eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.Z = IsZeroBit(result);
2286eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.C = carry;
2287eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                // APSR.V unchanged
2288eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
2289eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2290eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    return EmulateShiftImm(encoding, SRType_ROR);
2291eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
2292eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2293eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
2294eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2295eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
2296eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result.
2297eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
2298eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRORReg (ARMEncoding encoding)
2299eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
2300eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
2301eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
2302eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
2303eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
2304eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        shift_n = UInt(R[m]<7:0>);
2305eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2306eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        R[d] = result;
2307eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if setflags then
2308eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.N = result<31>;
2309eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.Z = IsZeroBit(result);
2310eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.C = carry;
2311eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // APSR.V unchanged
2312eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
2313eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2314eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    return EmulateShiftReg(encoding, SRType_ROR);
2315eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
2316eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2317eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
2318eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31].
2319eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen//
2320eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result.
2321eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag.
2322eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
2323eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny ChenEmulateInstructionARM::EmulateRRX (ARMEncoding encoding)
2324eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
2325eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
2326eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
2327eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
2328eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
2329eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
2330eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
2331eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
2332eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        else
2333eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            R[d] = result;
2334eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            if setflags then
2335eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.N = result<31>;
2336eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.Z = IsZeroBit(result);
2337eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.C = carry;
2338eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                // APSR.V unchanged
2339eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
2340eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2341eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    return EmulateShiftImm(encoding, SRType_RRX);
2342eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
2343eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
234441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
234541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type)
234641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
234741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
234841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
234982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    bool success = false;
235082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
235182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if (!success)
235282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        return false;
235382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
235482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if (ConditionPassed())
235582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    {
2356e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rd;    // the destination register
2357e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rm;    // the first operand register
2358e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t imm5;  // encoding for the shift amount
235982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        uint32_t carry; // the carry bit after the shift operation
236082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        bool setflags;
2361eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
2362eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // Special case handling!
2363eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // A8.6.139 ROR (immediate) -- Encoding T1
2364eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if (shift_type == SRType_ROR && encoding == eEncodingT1)
2365eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        {
2366eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
2367eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // have the same decoding of bit fields as the other Thumb2 shift operations.
2368eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            encoding = eEncodingT2;
2369eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        }
2370eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
237182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        switch (encoding) {
237282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingT1:
2373eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // Due to the above special case handling!
2374eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            assert(shift_type != SRType_ROR);
2375eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
237682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 2, 0);
237782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 5, 3);
237882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = !InITBlock();
237982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 10, 6);
238082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
238182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingT2:
2382eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // A8.6.141 RRX
2383eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            assert(shift_type != SRType_RRX);
2384eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
238582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 11, 8);
238682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 3, 0);
238782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = BitIsSet(opcode, 20);
238882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
238982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            if (BadReg(Rd) || BadReg(Rm))
239082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                return false;
239182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
239282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingA1:
239382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 15, 12);
239482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 3, 0);
239582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = BitIsSet(opcode, 20);
239682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 11, 7);
239782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
239882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        default:
239982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            return false;
240082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        }
240182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2402eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // A8.6.139 ROR (immediate)
2403eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if (shift_type == SRType_ROR && imm5 == 0)
2404eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            shift_type = SRType_RRX;
2405eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
240682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // Get the first operand.
240782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
240882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        if (!success)
240982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            return false;
241082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2411eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // Decode the shift amount if not RRX.
2412eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
241382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
241441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
241582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
241682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
241782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        EmulateInstruction::Context context;
241882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
241982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        context.SetNoArgs ();
242082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
242110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
2422ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
242382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    }
242482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    return true;
242582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen}
242682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
2427e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool
242841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny ChenEmulateInstructionARM::EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type)
2429e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{
243041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
2431e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2432e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    bool success = false;
2433e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
2434e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    if (!success)
2435e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        return false;
2436e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2437e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    if (ConditionPassed())
2438e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    {
2439e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rd;    // the destination register
2440e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rn;    // the first operand register
2441e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
2442e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t carry; // the carry bit after the shift operation
2443e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        bool setflags;
2444e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        switch (encoding) {
2445e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingT1:
2446e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 2, 0);
2447e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Rd;
2448e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 5, 3);
2449e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = !InITBlock();
2450e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
2451e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingT2:
2452e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 11, 8);
2453e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Bits32(opcode, 19, 16);
2454e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 3, 0);
2455e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = BitIsSet(opcode, 20);
2456e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
2457e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen                return false;
2458e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
2459e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingA1:
2460e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 15, 12);
2461e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Bits32(opcode, 3, 0);
2462e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 11, 8);
2463e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = BitIsSet(opcode, 20);
2464e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            if (Rd == 15 || Rn == 15 || Rm == 15)
2465e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen                return false;
2466e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
2467e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        default:
2468e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2469e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        }
2470e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2471e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the first operand.
2472e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
2473e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        if (!success)
2474e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2475e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the Rm register content.
2476e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success);
2477e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        if (!success)
2478e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2479e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2480e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the shift amount.
2481e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t amt = Bits32(val, 7, 0);
2482e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
248341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        uint32_t result = Shift_C(value, shift_type, amt, Bit32(m_inst_cpsr, CPSR_C), carry);
2484e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2485e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
2486e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        EmulateInstruction::Context context;
2487e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
2488e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        context.SetNoArgs ();
2489e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
249010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
2491e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
2492e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    }
2493e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    return true;
2494e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen}
2495e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
2496b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an
2497713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register.  Optionally the address just above the highest of those locations
2498b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register.
2499b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool
2500b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline TiceEmulateInstructionARM::EmulateLDM (ARMEncoding encoding)
2501b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{
2502b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0
2503b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    // ARM pseudo code...
2504b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if ConditionPassed()
2505b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
2506b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        address = R[n];
2507b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2508b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        for i = 0 to 14
2509b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if registers<i> == '1' then
2510b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                R[i] = MemA[address, 4]; address = address + 4;
2511b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if registers<15> == '1' then
2512b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            LoadWritePC (MemA[address, 4]);
2513b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2514b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
2515b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
2516b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2517b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif
2518b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2519b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    bool success = false;
2520b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
2521b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if (!success)
2522b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        return false;
2523b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2524b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if (ConditionPassed())
2525b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    {
2526b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        uint32_t n;
2527b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        uint32_t registers = 0;
2528b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        bool wback;
2529b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
2530b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        switch (encoding)
2531b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2532b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingT1:
2533b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’);
2534b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 10, 8);
2535b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 7, 0);
2536b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
2537b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsClear (registers, n);
2538b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                // if BitCount(registers) < 1 then UNPREDICTABLE;
2539b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (BitCount(registers) < 1)
2540b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2541b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
2542b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingT2:
2543b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if W == ’1’ && Rn == ’1101’ then SEE POP;
2544b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
2545b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 19, 16);
2546b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 15, 0);
2547b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0xdfff; // Make sure bit 13 is zero.
2548b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsSet (opcode, 21);
2549b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2550b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
2551b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if ((n == 15)
2552b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitCount (registers) < 2)
2553b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
2554b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2555b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2556b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
2557098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
2558b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2559b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2560b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
2561b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (wback
2562b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    && BitIsSet (registers, n))
2563b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2564b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
2565b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
2566b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingA1:
2567b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 19, 16);
2568b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 15, 0);
2569b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsSet (opcode, 21);
2570b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if ((n == 15)
2571b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitCount (registers) < 1))
2572b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2573b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
2574b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            default:
2575b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2576b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2577b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2578b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        int32_t offset = 0;
2579b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2580b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (!success)
2581b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            return false;
258285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
25839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
25849bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
25859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
25869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
25879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
2588b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2589b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        for (int i = 0; i < 14; ++i)
2590b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2591b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (BitIsSet (registers, i))
2592b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            {
259385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                context.type = EmulateInstruction::eContextRegisterPlusOffset;
25949bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
2595b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (wback && (n == 13)) // Pop Instruction
2596b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    context.type = EmulateInstruction::eContextPopRegisterOffStack;
2597b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2598b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                // R[i] = MemA [address, 4]; address = address + 4;
2599cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
2600b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (!success)
2601b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2602b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2603b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2604b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
2605b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2606b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                offset += addr_byte_size;
2607b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            }
2608b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2609b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2610b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (BitIsSet (registers, 15))
2611b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2612b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            //LoadWritePC (MemA [address, 4]);
261385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            context.type = EmulateInstruction::eContextRegisterPlusOffset;
26149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2615cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
2616b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (!success)
2617b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2618e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
2619668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
2620b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2621b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2622b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2623b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (wback && BitIsClear (registers, n))
2624b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
2625fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            // R[n] = R[n] + 4 * BitCount (registers)
2626fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            int32_t offset = addr_byte_size * BitCount (registers);
2627fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
26289bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2629b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2630b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
2631b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
2632b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
2633b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (wback && BitIsSet (registers, n))
2634b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            // R[n] bits(32) UNKNOWN;
2635713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
2636b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    }
2637b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    return true;
2638b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice}
2639713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2640713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers.
2641713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// The consecutive memorty locations end at this address and the address just below the lowest of those locations
2642713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// can optionally be written back tot he base registers.
2643713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool
2644713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding)
2645713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{
2646713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0
2647713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    // ARM pseudo code...
2648713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if ConditionPassed() then
2649713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        EncodingSpecificOperations();
2650713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = R[n] - 4*BitCount(registers) + 4;
2651713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2652713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        for i = 0 to 14
2653713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if registers<i> == ’1then
2654713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  R[i] = MemA[address,4]; address = address + 4;
2655713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2656713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if registers<15> == ’1then
2657713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            LoadWritePC(MemA[address,4]);
2658713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2659713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2660713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
2661713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif
2662713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2663713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    bool success = false;
2664713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
2665713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!success)
2666713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
2667713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2668713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (ConditionPassed())
2669713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    {
2670713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        uint32_t n;
2671713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        uint32_t registers = 0;
2672713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        bool wback;
2673713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
2674713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2675713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // EncodingSpecificOperations();
2676713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        switch (encoding)
2677713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
2678713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            case eEncodingA1:
2679713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
2680713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                n = Bits32 (opcode, 19, 16);
2681713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                registers = Bits32 (opcode, 15, 0);
2682713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                wback = BitIsSet (opcode, 21);
2683b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
2684713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
2685713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
2686713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                    return false;
2687713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2688713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                break;
2689713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2690713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            default:
2691713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
2692713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
2693713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // address = R[n] - 4*BitCount(registers) + 4;
2694713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2695713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        int32_t offset = 0;
2696713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2697713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2698713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
2699713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
2700713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2701713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size;
2702713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
27039bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
27049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
27059bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
27069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
27079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
2708713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2709713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // for i = 0 to 14
2710713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        for (int i = 0; i < 14; ++i)
2711713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
2712713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            // if registers<i> == ’1’ then
2713713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (BitIsSet (registers, i))
2714713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            {
2715713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  // R[i] = MemA[address,4]; address = address + 4;
27169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                  context.SetRegisterPlusOffset (dwarf_reg, offset);
2717cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2718713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  if (!success)
2719713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                      return false;
2720713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
2721713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                      return false;
2722713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  offset += addr_byte_size;
2723713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            }
2724713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
2725713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2726713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // if registers<15> == ’1’ then
2727713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        //     LoadWritePC(MemA[address,4]);
2728713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (BitIsSet (registers, 15))
2729713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
27309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2731cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
2732713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!success)
2733713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
273444c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen            // In ARMv5T and above, this is an interworking branch.
2735668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
2736713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
2737713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
2738713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2739713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
2740713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (wback && BitIsClear (registers, n))
2741713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
2742713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2743713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!success)
2744713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
2745fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
2746fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
2747fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
27489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
2749fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr = addr + offset;
2750713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
2751713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
2752713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
2753713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2754713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN;
2755713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (wback && BitIsSet (registers, n))
2756713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
2757713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    }
2758713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    return true;
2759713c2665a27096b68f3f8956222375354f1292f8Caroline Tice}
2760713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2761713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
2762713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
2763713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register.
27640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool
27650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline TiceEmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding)
27660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{
27670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0
27680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    // ARM pseudo code...
27690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if ConditionPassed() then
27700b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
27710b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        address = R[n] - 4*BitCount(registers);
27720b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
27730b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        for i = 0 to 14
27740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if registers<i> == ’1then
27750b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                  R[i] = MemA[address,4]; address = address + 4;
27760b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if registers<15> == ’1then
27770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                  LoadWritePC(MemA[address,4]);
27780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
27790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
27800b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
27810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif
27820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
27830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    bool success = false;
27840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
27850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if (!success)
27860b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        return false;
27870b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
27880b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if (ConditionPassed())
27890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    {
27900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        uint32_t n;
27910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        uint32_t registers = 0;
27920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        bool wback;
27930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
27940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        switch (encoding)
27950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
27960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            case eEncodingT1:
27970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’);
27980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                n = Bits32 (opcode, 19, 16);
27990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                registers = Bits32 (opcode, 15, 0);
2800b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
28010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                wback = BitIsSet (opcode, 21);
28020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE;
28040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if ((n == 15)
28050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    || (BitCount (registers) < 2)
28060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
28070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
28080b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
2810098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
28110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
28120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
28140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (wback && BitIsSet (registers, n))
28150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
28160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                break;
28180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28190b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            case eEncodingA1:
28200b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
28210b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                n = Bits32 (opcode, 19, 16);
28220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                registers = Bits32 (opcode, 15, 0);
28230b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                wback = BitIsSet (opcode, 21);
28240b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28250b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
28260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if ((n == 15) || (BitCount (registers) < 1))
28270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
28280b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28290b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                break;
28300b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28310b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            default:
28320b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
28330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
28340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
2835713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // address = R[n] - 4*BitCount(registers);
2836713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
28370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        int32_t offset = 0;
2838713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2839713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2840713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
2841713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
2842713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2843713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = address - (addr_byte_size * BitCount (registers));
28449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
28459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
28469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
28479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
28489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
28490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        for (int i = 0; i < 14; ++i)
28510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
28520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (BitIsSet (registers, i))
28530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            {
28540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // R[i] = MemA[address,4]; address = address + 4;
28559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
2856cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
28570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (!success)
28580b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
28590b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
28610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
28620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                offset += addr_byte_size;
28640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            }
28650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
28660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        // if registers<15> == ’1’ then
28680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        //     LoadWritePC(MemA[address,4]);
28690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (BitIsSet (registers, 15))
28700b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
28719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2872cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
28730b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!success)
28740b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
2875e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
2876668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
28770b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
28780b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
28790b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28800b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers);
28810b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (wback && BitIsClear (registers, n))
28820b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
28830b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
28840b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!success)
28850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
2886fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
2887fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
2888fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
28899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
2890fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr = addr + offset;
28910b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
28920b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
28930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
28940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
28950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
28960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (wback && BitIsSet (registers, n))
2897713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
28980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    }
28990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    return true;
29000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice}
290185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
2902713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
2903713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
2904713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register.
290585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool
290685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline TiceEmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding)
290785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{
290885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0
290985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if ConditionPassed() then
291085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        EncodingSpecificOperations();
291185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        address = R[n] + 4;
291285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
291385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        for i = 0 to 14
291485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if registers<i> == ’1then
291585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                  R[i] = MemA[address,4]; address = address + 4;
291685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if registers<15> == ’1then
291785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            LoadWritePC(MemA[address,4]);
291885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
291985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
292085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if wback && registers<n> == ’1then R[n] = bits(32) UNKNOWN;
292185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif
292285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
292385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    bool success = false;
292485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
292585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if (!success)
292685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        return false;
292785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
292885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if (ConditionPassed())
292985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    {
293085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        uint32_t n;
293185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        uint32_t registers = 0;
293285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        bool wback;
293385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
293485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        switch (encoding)
293585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
293685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            case eEncodingA1:
293785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
293885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                n = Bits32 (opcode, 19, 16);
293985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                registers = Bits32 (opcode, 15, 0);
294085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                wback = BitIsSet (opcode, 21);
294185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
294285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
294385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if ((n == 15) || (BitCount (registers) < 1))
294485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
294585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
294685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                break;
294785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            default:
294885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
294985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
295085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // address = R[n] + 4;
295185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
295285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        int32_t offset = 0;
2953713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2954713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2955713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
2956713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
2957713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
2958713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = address + addr_byte_size;
295985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
29609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
29619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
29629bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register dwarf_reg;
29639bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
29649bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
296585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
296685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        for (int i = 0; i < 14; ++i)
296785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
296885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (BitIsSet (registers, i))
296985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            {
297085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // R[i] = MemA[address,4]; address = address + 4;
297185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
29729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
2973cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
297485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if (!success)
297585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
297685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
297785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
297885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
297985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
298085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                offset += addr_byte_size;
298185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            }
298285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
298385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
298485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // if registers<15> == ’1’ then
298585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        //     LoadWritePC(MemA[address,4]);
298685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (BitIsSet (registers, 15))
298785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
29889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
2989cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
299085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!success)
299185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
2992e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
2993668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
299485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
299585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
299685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
299785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers);
299885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (wback && BitIsClear (registers, n))
299985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
300085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
300185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!success)
300285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
3003fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3004fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = addr_byte_size * BitCount (registers);
3005fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
30069bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3007fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr = addr + offset;
300885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
300985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
301085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
301185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
301285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
301385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (wback && BitIsSet (registers, n))
3014713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
301585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    }
301685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    return true;
301785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice}
30180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3019ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and
3020ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register.
3021ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb)
3022ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool
3023ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
3024ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{
3025ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0
3026ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    // ARM pseudo code...
3027ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (ConditionPassed())
3028ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    {
3029ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3030ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3031ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        address = if index then offset_addr else R[n];
3032ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        data = MemU[address,4];
3033ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if wback then R[n] = offset_addr;
3034ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if t == 15 then
3035ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3036ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        elsif UnalignedSupport() || address<1:0> = '00' then
3037ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            R[t] = data;
3038ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3039ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    }
3040ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif
3041ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3042ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    bool success = false;
3043ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    const uint32_t opcode = OpcodeAsUnsigned (&success);
3044ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (!success)
3045ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        return false;
3046ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3047ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (ConditionPassed())
3048ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    {
3049ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t Rt; // the destination register
3050ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t Rn; // the base register
3051ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t imm32; // the immediate offset used to form the address
3052ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        addr_t offset_addr; // the offset address
3053ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        addr_t address; // the calculated address
3054ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t data; // the literal data value from memory load
3055ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        bool add, index, wback;
3056ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        switch (encoding) {
3057ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        case eEncodingT1:
3058ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            Rt = Bits32(opcode, 5, 3);
3059ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            Rn = Bits32(opcode, 2, 0);
3060ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3061ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            // index = TRUE; add = TRUE; wback = FALSE
3062ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            add = true;
3063ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            index = true;
3064ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            wback = false;
3065ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            break;
3066ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        default:
3067ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3068ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3069ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
3070ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (!success)
3071ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3072ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (add)
3073ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            offset_addr = base + imm32;
3074ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else
3075ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            offset_addr = base - imm32;
3076ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3077ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        address = (index ? offset_addr : base);
3078ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3079ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (wback)
3080ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
30819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            EmulateInstruction::Context ctx;
30829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            ctx.type = EmulateInstruction::eContextRegisterPlusOffset;
30839bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Register dwarf_reg;
30849bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
30859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base));
30869bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
3087ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3088ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3089ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3090ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3091ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        // Prepare to write to the Rt register.
30929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
30939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
30949bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
3095ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3096ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        // Read memory from the address.
3097cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        data = MemURead(context, address, 4, 0, &success);
3098ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (!success)
3099ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3100ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3101ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (Rt == 15)
3102ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
3103ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (Bits32(address, 1, 0) == 0)
3104ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            {
3105668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen                if (!LoadWritePC(context, data))
3106ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                    return false;
3107ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            }
3108ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            else
3109ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3110ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3111ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3112ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
3113ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3114ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3115ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3116ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else
3117ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3118ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    }
3119ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    return true;
3120ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen}
3121ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3122af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3123af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3124af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
3125fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool
3126fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::EmulateSTM (ARMEncoding encoding)
3127fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{
3128fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0
3129fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if ConditionPassed() then
3130fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3131fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        address = R[n];
3132fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3133fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        for i = 0 to 14
3134fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if registers<i> == ’1then
3135fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
3136fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3137fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                else
3138fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    MemA[address,4] = R[i];
3139fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                address = address + 4;
3140fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3141fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if registers<15> == ’1then // Only possible for encoding A1
3142fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            MemA[address,4] = PCStoreValue();
3143fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if wback then R[n] = R[n] + 4*BitCount(registers);
3144fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif
3145fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3146fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    bool success = false;
3147fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
3148fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if (!success)
3149fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        return false;
3150fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3151fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if (ConditionPassed ())
3152fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    {
3153fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        uint32_t n;
3154fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        uint32_t registers = 0;
3155fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        bool wback;
3156fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3157fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3158fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3159fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        switch (encoding)
3160fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
3161fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingT1:
3162fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE;
3163fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 10, 8);
3164fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 7, 0);
3165b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3166fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = true;
3167fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3168fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if BitCount(registers) < 1 then UNPREDICTABLE;
3169fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if (BitCount (registers) < 1)
3170fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3171fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3172fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
3173fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3174fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingT2:
3175fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’);
3176fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 19, 16);
3177fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 15, 0);
3178b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3179fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = BitIsSet (opcode, 21);
3180fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3181fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3182fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if ((n == 15) || (BitCount (registers) < 2))
3183fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3184fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3185fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
3186fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if (wback && BitIsSet (registers, n))
3187fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3188fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3189fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
3190fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3191fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingA1:
3192fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3193fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 19, 16);
3194fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 15, 0);
3195fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = BitIsSet (opcode, 21);
3196fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3197fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3198fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
3199fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
3200fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3201fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
3202fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3203fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            default:
3204fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3205fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3206fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3207fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // address = R[n];
3208fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        int32_t offset = 0;
3209fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3210fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (!success)
3211fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            return false;
3212fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
32139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
32149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
32159bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        Register base_reg;
32169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3217fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3218fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // for i = 0 to 14
3219fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        for (int i = 0; i < 14; ++i)
3220fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
3221fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            int lowest_set_bit = 14;
3222fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            // if registers<i> == ’1’ then
3223fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (BitIsSet (registers, i))
3224fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            {
3225fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  if (i < lowest_set_bit)
3226fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      lowest_set_bit = i;
3227fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  // if i == n && wback && i != LowestSetBit(registers) then
3228fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  if ((i == n) && wback && (i != lowest_set_bit))
3229fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3230fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      WriteBits32UnknownToMemory (address + offset);
3231fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  else
3232fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  {
3233fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                     // MemA[address,4] = R[i];
3234fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3235fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      if (!success)
3236fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                          return false;
3237fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
32389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      Register data_reg;
32399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
32409bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3241cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
3242fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                          return false;
3243fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  }
3244fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3245fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  // address = address + 4;
3246fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  offset += addr_byte_size;
3247fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            }
3248fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3249fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3250fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // if registers<15> == ’1’ then // Only possible for encoding A1
3251fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //     MemA[address,4] = PCStoreValue();
3252fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (BitIsSet (registers, 15))
3253fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
32549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Register pc_reg;
32559bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
32569bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
3257fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3258fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (!success)
3259fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3260fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3261cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3262fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3263fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3264fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3265fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // if wback then R[n] = R[n] + 4*BitCount(registers);
3266fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (wback)
3267fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
3268fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = addr_byte_size * BitCount (registers);
3269fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
32709bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3271fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr_t data = address + offset;
3272fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3273fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
3274fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
3275fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    }
3276fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    return true;
3277fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice}
3278fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3279af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
3280af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
3281af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
32821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool
32831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline TiceEmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding)
32841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{
32851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0
32861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if ConditionPassed() then
32871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        EncodingSpecificOperations();
32881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        address = R[n] - 4*BitCount(registers) + 4;
32891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
32901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        for i = 0 to 14
32911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if registers<i> == ’1then
32921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
32931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN;
32941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                else
32951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    MemA[address,4] = R[i];
32961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                address = address + 4;
32971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
32981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if registers<15> == ’1then
32991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            MemA[address,4] = PCStoreValue();
33001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if wback then R[n] = R[n] - 4*BitCount(registers);
33021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif
33031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    bool success = false;
33051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
33061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if (!success)
33071511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        return false;
33081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33091511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if (ConditionPassed ())
33101511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    {
33111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        uint32_t n;
33121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        uint32_t registers = 0;
33131511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        bool wback;
33141511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
33151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // EncodingSpecificOperations();
33171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        switch (encoding)
33181511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
33191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            case eEncodingA1:
33201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
33211511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                n = Bits32 (opcode, 19, 16);
33221511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                registers = Bits32 (opcode, 15, 0);
33231511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                wback = BitIsSet (opcode, 21);
33241511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33251511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
33261511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
33271511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    return false;
33281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                break;
33291511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            default:
33301511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
33311511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
33321511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // address = R[n] - 4*BitCount(registers) + 4;
33341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        int32_t offset = 0;
33351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
33361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (!success)
33371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            return false;
33381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        address = address - (addr_byte_size * BitCount (registers)) + 4;
33401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33411511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        EmulateInstruction::Context context;
33421511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
33431511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        Register base_reg;
33441511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
33451511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33461511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // for i = 0 to 14
33471511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        for (int i = 0; i < 14; ++i)
33481511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
33491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            int lowest_bit_set = 14;
33501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            // if registers<i> == ’1’ then
33511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (BitIsSet (registers, i))
33521511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            {
33531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if (i < lowest_bit_set)
33541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    lowest_bit_set = i;
33551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                //if i == n && wback && i != LowestSetBit(registers) then
33561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if ((i == n) && wback && (i != lowest_bit_set))
33571511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    // MemA[address,4] = bits(32) UNKNOWN;
33581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    WriteBits32UnknownToMemory (address + offset);
33591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                else
33601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                {
33611511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    // MemA[address,4] = R[i];
33621511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
33631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    if (!success)
33641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                        return false;
33651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    Register data_reg;
33671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
33681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3369cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
33701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                        return false;
33711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                }
33721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // address = address + 4;
33741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                offset += addr_byte_size;
33751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            }
33761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
33771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // if registers<15> == ’1’ then
33791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        //    MemA[address,4] = PCStoreValue();
33801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (BitIsSet (registers, 15))
33811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
33821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            Register pc_reg;
33831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
33841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
33851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
33861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (!success)
33871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
33881511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
3389cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
33901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
33911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
33921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
33931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // if wback then R[n] = R[n] - 4*BitCount(registers);
33941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (wback)
33951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
3396af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
33971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
33981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.SetImmediateSigned (offset);
33991511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            addr_t data = address + offset;
34001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
34011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
34021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
34031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    }
34041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    return true;
34051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice}
34061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
3407af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
3408af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
3409af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register.
3410b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool
3411b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline TiceEmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding)
3412b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{
3413b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0
3414b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if ConditionPassed() then
3415b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3416b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        address = R[n] - 4*BitCount(registers);
3417b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3418b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        for i = 0 to 14
3419b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if registers<i> == ’1then
3420b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
3421b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
3422b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                else
3423b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    MemA[address,4] = R[i];
3424b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                address = address + 4;
3425b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3426b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if registers<15> == ’1then // Only possible for encoding A1
3427b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            MemA[address,4] = PCStoreValue();
3428b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3429b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if wback then R[n] = R[n] - 4*BitCount(registers);
3430b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif
3431b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3432b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3433b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    bool success = false;
3434b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
3435b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if (!success)
3436b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        return false;
3437b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3438b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if (ConditionPassed ())
3439b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    {
3440b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        uint32_t n;
3441b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        uint32_t registers = 0;
3442b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        bool wback;
3443b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3444b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3445b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3446b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        switch (encoding)
3447b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3448b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            case eEncodingT1:
3449b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if W == ’1’ && Rn == ’1101’ then SEE PUSH;
3450b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
3451b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
3452b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // See PUSH
3453b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
3454b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’);
3455b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                n = Bits32 (opcode, 19, 16);
3456b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = Bits32 (opcode, 15, 0);
3457b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
3458b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                wback = BitIsSet (opcode, 21);
3459b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3460b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((n == 15) || BitCount (registers) < 2)
3461b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
3462b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if wback && registers<n> == ’1’ then UNPREDICTABLE;
3463b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (wback && BitIsSet (registers, n))
3464b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
3465b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                break;
3466b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3467b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            case eEncodingA1:
3468b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH;
3469b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
3470b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
3471b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // See Push
3472b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
3473b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3474b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                n = Bits32 (opcode, 19, 16);
3475b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = Bits32 (opcode, 15, 0);
3476b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                wback = BitIsSet (opcode, 21);
3477b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3478b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((n == 15) || BitCount (registers) < 1)
3479b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
3480b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                break;
3481b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3482b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            default:
3483b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3484b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3485b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3486b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // address = R[n] - 4*BitCount(registers);
3487b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3488b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        int32_t offset = 0;
3489b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3490b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (!success)
3491b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        return false;
3492b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3493b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        address = address - (addr_byte_size * BitCount (registers));
3494b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3495b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        EmulateInstruction::Context context;
3496b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
3497b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        Register base_reg;
3498b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3499b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3500b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // for i = 0 to 14
3501b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        for (int i = 0; i < 14; ++i)
3502b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3503b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            uint32_t lowest_set_bit = 14;
3504b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            // if registers<i> == ’1’ then
3505b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (BitIsSet (registers, i))
3506b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            {
3507b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (i < lowest_set_bit)
3508b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    lowest_set_bit = i;
3509b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if i == n && wback && i != LowestSetBit(registers) then
3510b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((i == n) && wback && (i != lowest_set_bit))
3511b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
3512b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    WriteBits32UnknownToMemory (address + offset);
3513b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                else
3514b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
3515b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // MemA[address,4] = R[i];
3516b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3517b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    if (!success)
3518b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                        return false;
3519b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3520b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    Register data_reg;
3521b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3522b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3523cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3524b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                        return false;
3525b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
3526b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3527b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // address = address + 4;
3528b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                offset += addr_byte_size;
3529b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            }
3530b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3531b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3532b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // if registers<15> == ’1’ then // Only possible for encoding A1
3533b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        //     MemA[address,4] = PCStoreValue();
3534b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (BitIsSet (registers, 15))
3535b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3536b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            Register pc_reg;
3537b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3538b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
3539b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3540b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (!success)
3541b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3542b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3543cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3544b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3545b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3546b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3547b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // if wback then R[n] = R[n] - 4*BitCount(registers);
3548b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (wback)
3549b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
3550af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
3551af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3552af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.SetImmediateSigned (offset);
3553af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            addr_t data = address + offset;
3554af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3555af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
3556af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3557af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    }
3558af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    return true;
3559af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice}
3560af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3561af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
3562af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations start just above this address, and the address of the last
3563af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
3564af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool
3565af556564f80fd417a9158754f5e2ee692e183f6dCaroline TiceEmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding)
3566af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{
3567af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0
3568af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if ConditionPassed() then
3569af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        EncodingSpecificOperations();
3570af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        address = R[n] + 4;
3571af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3572af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        for i = 0 to 14
3573af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if registers<i> == ’1then
3574af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if i == n && wback && i != LowestSetBit(registers) then
3575af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    MemA[address,4] = bits(32) UNKNOWN;
3576af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                else
3577af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    MemA[address,4] = R[i];
3578af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                address = address + 4;
3579af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3580af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if registers<15> == ’1then
3581af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            MemA[address,4] = PCStoreValue();
3582af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3583af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if wback then R[n] = R[n] + 4*BitCount(registers);
3584af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif
3585af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3586af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    bool success = false;
3587af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
3588af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if (!success)
3589af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        return false;
3590af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3591af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if (ConditionPassed())
3592af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    {
3593af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t n;
3594af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t registers = 0;
3595af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        bool wback;
3596af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3597af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3598af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // EncodingSpecificOperations();
3599af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        switch (encoding)
3600af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3601af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            case eEncodingA1:
3602af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == ’1’);
3603af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                n = Bits32 (opcode, 19, 16);
3604af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                registers = Bits32 (opcode, 15, 0);
3605af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                wback = BitIsSet (opcode, 21);
3606af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3607af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3608af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if ((n == 15) && (BitCount (registers) < 1))
3609af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    return false;
3610af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                break;
3611af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            default:
3612af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
3613af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3614af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // address = R[n] + 4;
3615af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3616af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        int32_t offset = 0;
3617af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3618af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (!success)
3619af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            return false;
3620af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3621af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        address = address + addr_byte_size;
3622af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3623af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        EmulateInstruction::Context context;
3624af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
3625af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        Register base_reg;
3626af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3627af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3628af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t lowest_set_bit = 14;
3629af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // for i = 0 to 14
3630af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        for (int i = 0; i < 14; ++i)
3631af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3632af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            // if registers<i> == ’1’ then
3633af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (BitIsSet (registers, i))
3634af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            {
3635af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if (i < lowest_set_bit)
3636af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    lowest_set_bit = i;
3637af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // if i == n && wback && i != LowestSetBit(registers) then
3638af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if ((i == n) && wback && (i != lowest_set_bit))
3639af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    // MemA[address,4] = bits(32) UNKNOWN;
3640af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    WriteBits32UnknownToMemory (address + offset);
3641af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // else
3642af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                else
3643af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                {
3644af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    // MemA[address,4] = R[i];
3645af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3646af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    if (!success)
3647af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                        return false;
3648af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3649af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    Register data_reg;
3650af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3651af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3652cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
3653af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                        return false;
3654af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                }
3655af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3656af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // address = address + 4;
3657af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                offset += addr_byte_size;
3658af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            }
3659af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3660af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3661af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // if registers<15> == ’1’ then
3662af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            // MemA[address,4] = PCStoreValue();
3663af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (BitIsSet (registers, 15))
3664af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3665af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            Register pc_reg;
3666af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
3667af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
3668af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
3669af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (!success)
3670af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            return false;
3671af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3672cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, address + offset, pc + 8, addr_byte_size))
3673af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
3674af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
3675af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
3676af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // if wback then R[n] = R[n] + 4*BitCount(registers);
3677af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (wback)
3678af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
3679b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            offset = addr_byte_size * BitCount (registers);
3680b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3681b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.SetImmediateSigned (offset);
3682b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            addr_t data = address + offset;
3683b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
3684b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
3685b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
3686b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    }
3687b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    return true;
3688b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice}
36897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
36907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
36917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
36927fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool
36937fac857ec72051dc0a91b027719c275ea672a470Caroline TiceEmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding)
36947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{
36957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0
36967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if ConditionPassed() then
36977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
36987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
36997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        address = if index then offset_addr else R[n];
37007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if UnalignedSupport() || address<1:0> == ’00’ then
37017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            MemU[address,4] = R[t];
37027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else // Can only occur before ARMv7
37037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            MemU[address,4] = bits(32) UNKNOWN;
37047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if wback then R[n] = offset_addr;
37057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif
37067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    bool success = false;
37087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
37097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if (!success)
37107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        return false;
37117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if (ConditionPassed())
37137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    {
37147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
37157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t t;
37177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t n;
37187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t imm32;
37197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool index;
37207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool add;
37217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool wback;
37227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
37237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        switch (encoding)
37247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
37257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT1:
37267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:’00’, 32);
37277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 2, 0);
37287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 5, 3);
37297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 10, 6) << 2;
37307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
37327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
37337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = false;
37347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
37357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
37367fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37377fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT2:
37387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:’00’, 32);
37397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 10, 8);
37407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = 13;
37417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
37427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
37447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
37457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = true;
37467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
37477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
37487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT3:
37507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if Rn == ’1111’ then UNDEFINED;
37517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
37527fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
37537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
37557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 15, 12);
37567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 19, 16);
37577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
37587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
37607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
37617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = true;
37627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
37637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if t == 15 then UNPREDICTABLE;
37657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if (t == 15)
37667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
37677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
37687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT4:
37707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRT;
37717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if Rn == ’1101’ && P == ’1’ && U == ’0’ && W == ’1’ && imm8 == ’00000100’ then SEE PUSH;
37727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED;
37737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if ((Bits32 (opcode, 19, 16) == 15)
37747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
37757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
37767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
37787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 15, 12);
37797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 19, 16);
37807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
37817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
37837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = BitIsSet (opcode, 10);
37847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = BitIsSet (opcode, 9);
37857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = BitIsSet (opcode, 8);
37867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
37887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if ((t == 15) || (wback && (n == t)))
37897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
37907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
37917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            default:
37937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
37947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
37957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
37967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        addr_t offset_addr;
37977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        addr_t address;
3798b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
37997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
38007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
38017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (!success)
38027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            return false;
38037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
38047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (add)
38057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            offset_addr = base_address + imm32;
38067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
38077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            offset_addr = base_address - imm32;
38087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
38097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // address = if index then offset_addr else R[n];
38107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (index)
38117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            address = offset_addr;
38127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
38137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            address = base_address;
38147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
38157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        EmulateInstruction::Context context;
38167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        context.type = eContextRegisterStore;
38177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        Register base_reg;
38187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
38197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
38207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // if UnalignedSupport() || address<1:0> == ’00’ then
38217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
38227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
38237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            // MemU[address,4] = R[t];
38247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
38257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            if (!success)
38267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
38277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
38287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            Register data_reg;
38297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
38307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            int32_t offset = address - base_address;
38317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3832cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, address, data, addr_byte_size))
38337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
38347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
38357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
38367fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
38377fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            // MemU[address,4] = bits(32) UNKNOWN;
38387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            WriteBits32UnknownToMemory (address);
38397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
38407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
38417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // if wback then R[n] = offset_addr;
38427fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (wback)
38437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
38447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.type = eContextRegisterLoad;
38457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.SetAddress (offset_addr);
38467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
38477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
38487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
38497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    }
38507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    return true;
38517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice}
3852af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
38533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
38543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory.   The offset register value can optionally be shifted.
38553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool
38563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline TiceEmulateInstructionARM::EmulateSTRRegister (ARMEncoding encoding)
38573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{
38583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0
38593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if ConditionPassed() then
38603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
38613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
38623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
38633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        address = if index then offset_addr else R[n];
38643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if t == 15 then // Only possible for encoding A1
38653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = PCStoreValue();
38663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
38673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = R[t];
38683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then
38693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            MemU[address,4] = data;
38703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else // Can only occur before ARMv7
38713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            MemU[address,4] = bits(32) UNKNOWN;
38723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if wback then R[n] = offset_addr;
38733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif
38743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
38753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    bool success = false;
38763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
38773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if (!success)
38783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        return false;
38793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
38803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if (ConditionPassed())
38813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    {
38823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
38833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
38843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t t;
38853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t n;
38863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t m;
38873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        ARM_ShifterType shift_t;
38883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t shift_n;
38893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool index;
38903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool add;
38913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool wback;
38923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
38933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
38943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        switch (encoding)
38953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
38963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingT1:
38973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
38983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
38993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 2, 0);
39003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 5, 3);
39013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 8, 6);
39023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
39043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = true;
39053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = true;
39063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = false;
39073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
39093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_t = SRType_LSL;
39103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = 0;
39113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
39123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingT2:
39143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if Rn == ’1111’ then UNDEFINED;
39153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (Bits32 (opcode, 19, 16) == 15)
39163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
39173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
39193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 15, 12);
39203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 19, 16);
39213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 3, 0);
39223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
39243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = true;
39253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = true;
39263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = false;
39273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
39293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_t = SRType_LSL;
39303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
39313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if t == 15 || BadReg(m) then UNPREDICTABLE;
39333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if ((t == 15) || (BadReg (m)))
39343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
39353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
39363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingA1:
39383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            {
39393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if P == ’0’ && W == ’1’ then SEE STRT;
39403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
39413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 15, 12);
39423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 19, 16);
39433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 3, 0);
39443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = (P == ’1’);	add = (U == ’1’);	wback = (P == ’0’) || (W == ’1’);
39463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = BitIsSet (opcode, 24);
39473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = BitIsSet (opcode, 23);
39483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
39493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
39513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                uint32_t typ = Bits32 (opcode, 6, 5);
39523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
39533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = DecodeImmShift(typ, imm5, shift_t);
39543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if m == 15 then UNPREDICTABLE;
39563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (m == 15)
39573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
39583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
39603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (wback && ((n == 15) || (n == t)))
39613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
39623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
39643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            }
39653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            default:
39663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
39673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
39683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t offset_addr;
39703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t address;
39713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        int32_t offset = 0;
39723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
39743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
39753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
39763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
39783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
39793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
39803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
39823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset = Shift (Rm_data, shift_t, shift_n, Bit32(m_inst_cpsr, CPSR_C));
39833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
39853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (add)
39863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            offset_addr = base_address + offset;
39873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
39883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            offset_addr = base_address - offset;
39893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // address = if index then offset_addr else R[n];
39913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (index)
39923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            address = offset_addr;
39933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
39943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            address = base_address;
39953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
39963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t data;
39973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if t == 15 then // Only possible for encoding A1
39983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (t == 15)
39993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // data = PCStoreValue();
40003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
40013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
40023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // data = R[t];
40033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
40043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
40063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
40073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        EmulateInstruction::Context context;
40093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        context.type = eContextRegisterStore;
40103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if UnalignedSupport() || address<1:0> == ’00’ || CurrentInstrSet() == InstrSet_ARM then
40123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (UnalignedSupport ()
40133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            || (BitIsClear (address, 1) && BitIsClear (address, 0))
40143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            || CurrentInstrSet() == eModeARM)
40153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
40163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // MemU[address,4] = data;
40173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            Register base_reg;
40193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
40203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            Register data_reg;
40223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
40233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4025cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, address, data, addr_byte_size))
40263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
40273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
40293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
40303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // MemU[address,4] = bits(32) UNKNOWN;
40313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            WriteBits32UnknownToMemory (address);
40323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if wback then R[n] = offset_addr;
40343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (wback)
40353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
40363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.type = eContextRegisterLoad;
40373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.SetAddress (offset_addr);
40383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
40393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
40403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
40413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
40423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    }
40433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    return true;
40443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice}
404573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
404673a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool
404773a29de4b8f59594fd7a559c05fa795afe754551Caroline TiceEmulateInstructionARM::EmulateSTRBThumb (ARMEncoding encoding)
404873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{
404973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0
405073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if ConditionPassed() then
405173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
405273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
405373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        address = if index then offset_addr else R[n];
405473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        MemU[address,1] = R[t]<7:0>;
405573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if wback then R[n] = offset_addr;
405673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif
405773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
405873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
405973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    bool success = false;
406073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    const uint32_t opcode = OpcodeAsUnsigned (&success);
406173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if (!success)
406273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        return false;
406373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
406473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if (ConditionPassed ())
406573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    {
406673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t t;
406773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t n;
406873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t imm32;
406973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool index;
407073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool add;
407173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool wback;
407273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
407373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        switch (encoding)
407473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        {
407573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT1:
407673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
407773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 2, 0);
407873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 5, 3);
407973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 10, 6);
408073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
408173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
408273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = true;
408373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = true;
408473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = false;
408573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
408673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
408773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT2:
408873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if Rn == ’1111’ then UNDEFINED;
408973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
409073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
409173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
409273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
409373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 15, 12);
409473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 19, 16);
409573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
409673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
409773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
409873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = true;
409973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = true;
410073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = false;
410173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
410273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if BadReg(t) then UNPREDICTABLE;
410373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (BadReg (t))
410473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
410573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
410673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
410773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT3:
410873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if P == ’1’ && U == ’1’ && W == ’0’ then SEE STRBT;
410973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if Rn == ’1111’ || (P == ’0’ && W == ’0’) then UNDEFINED;
411073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
411173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
411273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
411373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
411473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 15, 12);
411573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 19, 16);
411673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
411773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
411873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = (P == ’1’); add = (U == ’1’); wback = (W == ’1’);
411973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = BitIsSet (opcode, 10);
412073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = BitIsSet (opcode, 9);
412173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = BitIsSet (opcode, 8);
412273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
412373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
412473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if ((BadReg (t)) || (wback && (n == t)))
412573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
412673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
412773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
412873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            default:
412973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                return false;
413073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        }
413173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
413273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t offset_addr;
413373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t address;
413473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
413573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (!success)
413673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
413773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
413873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
413973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (add)
414073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            offset_addr = base_address + imm32;
414173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        else
414273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            offset_addr = base_address - imm32;
414373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
414473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // address = if index then offset_addr else R[n];
414573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (index)
414673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            address = offset_addr;
414773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        else
414873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            address = base_address;
414973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
4150cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        // MemU[address,1] = R[t]<7:0>
415173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        Register base_reg;
415273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
415373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
415473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        Register data_reg;
415573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
415673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
415773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        EmulateInstruction::Context context;
415873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        context.type = eContextRegisterStore;
415973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
416073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
416173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
416273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (!success)
416373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
416473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
416573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        data = Bits32 (data, 7, 0);
416673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
4167cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        if (!MemUWrite (context, address, data, 1))
416873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
416973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
417073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // if wback then R[n] = offset_addr;
417173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (wback)
417273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        {
417373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            context.type = eContextRegisterLoad;
417473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            context.SetAddress (offset_addr);
417573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
417673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                return false;
417773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        }
417873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
417973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    }
418073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
418173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    return true;
418273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice}
41833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
41842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode*
41852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
418664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
41872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static ARMOpcode
41882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    g_arm_opcodes[] =
41892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
41902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
41912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Prologue instructions
41922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
41932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
41942b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push register(s)
41959f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
41969f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
41972b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
41982b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // set r7 to point to a stack offset
41999f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
4200c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"},
4201e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // copy the stack pointer to ip
42029f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
42039f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
4204c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"},
42052b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // adjust the stack pointer
4207c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"},
42082b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push one register
42102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
4211c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0x0fff0000, 0x052d0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
42122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // vector push consecutive extension register(s)
42149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
42159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
42162b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42172b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
4218587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        // Epilogue instructions
42192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
42202b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42219f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
42229f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
42239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
4224b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
4225b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
4226b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
4227b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        // Supervisor Call (previously Software Interrupt)
4228b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
42293b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
42303b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
42313b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
42323b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // Branch instructions
42333b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
4234b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"},
4235383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
4236383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
4237383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
4238383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
4239ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        // for example, "bx lr"
4240ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
4241b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
4242b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
424328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        // Data-processing instructions
424428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        //----------------------------------------------------------------------
424528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        // move bitwise not
42469f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMVNRdImm, "mvn{s} <Rd>, #<const>"},
424782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // asr (immediate)
424882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
42492ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // asr (register)
4250e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
42512ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (immediate)
42522ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
42532ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (register)
42542ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
42552ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (immediate)
42562ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
42572ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (register)
42582ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
4259eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // rrx is a special case encoding of ror (immediate)
4260eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
4261eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (immediate)
4262eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
4263eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (register)
4264eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
426528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen
426628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        //----------------------------------------------------------------------
4267b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        // Load instructions
4268b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
42690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
4270713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
427185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
4272fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
4273fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4274fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
4275fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // Store instructions
4276fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
42771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        { 0x0fd00000, 0x08800000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
4278b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        { 0x0fd00000, 0x08000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
4279af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        { 0x0fd00000, 0x09000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
42803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        { 0x0fd00000, 0x09800000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
42813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        { 0x0e500010, 0x06000000, ARMvAll,      eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }
42821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
4283b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
42842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    };
42852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
42862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    for (size_t i=0; i<k_num_arm_opcodes; ++i)
42882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
42892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
42902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            return &g_arm_opcodes[i];
42912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    }
42922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    return NULL;
42932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
42942b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
42962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode*
42972b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
4298347320d16d98cffaadf3f888569100c43b241068Johnny Chen{
42992b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
43002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static ARMOpcode
43012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    g_thumb_opcodes[] =
43022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
43032b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
43042b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Prologue instructions
43052b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
43062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
43072b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push register(s)
43089f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
43099f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
43109f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
43112b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
43122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // set r7 to point to a stack offset
43139f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
4314e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // copy the stack pointer to r7
43159f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
4316e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
43179f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
43182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
4319c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        // PC-relative load into register (see also EmulateAddSPRm)
4320c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
43212b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
43222b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // adjust the stack pointer
4323c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"},
4324c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"},
4325d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"},
4326d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"},
43272b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
43282b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // vector push consecutive extension register(s)
4329d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
4330d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
43312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
43322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
43332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Epilogue instructions
43342b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
43352b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
4336c28a76dfb091742a508c568d77fc52975afb5e3fJohnny Chen        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"},
43379f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
43389f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
43399f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
4340d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
4341d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
4342b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
4343b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
4344b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        // Supervisor Call (previously Software Interrupt)
4345b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
4346c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
4347c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
4348c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        //----------------------------------------------------------------------
4349c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        // If Then makes up to four following instructions conditional.
4350c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        //----------------------------------------------------------------------
43513b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
43523b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
43533b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
43543b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // Branch instructions
43553b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
43563b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
43573b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
43583b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        { 0xffff8000, 0x0000e000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"},
43599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
4360b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"},
4361383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // J1 == J2 == 1
4362383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xf800f800, 0xf000f800, ARMV4T_ABOVE,  eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
4363383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // J1 == J2 == 1
4364383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xf800e800, 0xf000e800, ARMV5_ABOVE,   eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
4365383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
4366ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        // for example, "bx lr"
4367ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
436853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        // compare and branch
436953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
437060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        // table branch byte
437160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
437260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        // table branch halfword
437360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
4374b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
4375b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
437626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Data-processing instructions
437726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        //----------------------------------------------------------------------
43789f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
437926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
4380d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        // Can update PC!
43819f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
4382338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        // move from high register to high register
43839f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
4384338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        // move from low register to low register
43859f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
4386357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        // move immediate
43879f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
43889f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
438928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        // move bitwise not
43909f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMVNRdImm, "mvn{s} <Rd>, #<const>"},
4391d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        // compare a register with immediate
43929f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPRnImm, "cmp<c> <Rn>, #imm8"},
4393e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        // compare Rn with Rm (Rn and Rm both from r0-r7)
43949f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCMPRnRm, "cmp<c> <Rn>, <Rm>"},
4395e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        // compare Rn with Rm (Rn and Rm not both from r0-r7)
43969f687729f0a2fff5dde65ce789c3a02e84c2ffccJohnny Chen        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCMPRnRm, "cmp<c> <Rn>, <Rm>"},
439782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // asr (immediate)
439882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
43994d896db529a5fef200333ef673976528319279bdJohnny Chen        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
4400e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // asr (register)
4401e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
4402e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
44032ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (immediate)
44042ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
44052ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
44062ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (register)
44072ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
44082ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
44092ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (immediate)
44102ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
44112ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
44122ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (register)
4413eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
44142ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
4415eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // rrx is a special case encoding of ror (immediate)
4416eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
4417eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (immediate)
4418eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
4419eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (register)
4420eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
4421eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
442226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
442326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        //----------------------------------------------------------------------
4424b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        // Load instructions
4425b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
4426b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
44270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
4428ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
4429c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        { 0xfffff800, 0x00006800, ARMvAll,       eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
4430c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        // Thumb2 PC-relative load into register
4431fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
4432fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4433fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
4434fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // Store instructions
4435fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
4436fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
4437b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
44387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
44397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>{,#<imm>}]" },
44407fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [SP,#<imm>]" },
44417fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt [<Rn>,#<imm12>]" },
44423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt> [<Rn>,#+/-<imm8>]" },
44433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> {<Rn> <Rm>]" },
444473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt> [<Rn> <Rm> {lsl #imm2>}]" },
444573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> [<Rn> #<imm5>]" },
444673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt> [<Rn> #<imm12>]" },
444773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> [<Rn>, #+/-<imm8>]{!}" }
44482b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    };
44492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
44502b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
44512b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
44522b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
44532b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
44542b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            return &g_thumb_opcodes[i];
44552b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    }
44562b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    return NULL;
44572b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
445864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
445931e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool
4460395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
446131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{
446231e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    m_arm_isa = 0;
4463395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    const char *arch_cstr = arch.AsCString ();
4464395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    if (arch_cstr)
4465395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    {
4466395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
4467395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
4468395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
4469395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
4470395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
4471395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
4472395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
4473395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
4474395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
4475395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
447631e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    }
447731e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    return m_arm_isa != 0;
447831e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton}
447931e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton
448031e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton
448164c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
448264c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction ()
448364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
448464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool success = false;
448564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
448664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (success)
448764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
448864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
448964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (success)
449064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
44919bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Context read_inst_context;
44929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            read_inst_context.type = eContextReadOpcode;
44939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            read_inst_context.SetNoArgs ();
44949bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
449564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (m_inst_cpsr & MASK_CPSR_T)
449664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
449764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                m_inst_mode = eModeThumb;
4498cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
449964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
450064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if (success)
450164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                {
450264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0))
450364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    {
450464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                        m_inst.opcode_type = eOpcode16;
450564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                        m_inst.opcode.inst16 = thumb_opcode;
450664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    }
450764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    else
450864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    {
450964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                        m_inst.opcode_type = eOpcode32;
4510cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                        m_inst.opcode.inst32 = (thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success);
451164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    }
451264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                }
451364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
451464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            else
451564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
451664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                m_inst_mode = eModeARM;
451764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                m_inst.opcode_type = eOpcode32;
4518cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                m_inst.opcode.inst32 = MemARead(read_inst_context, pc, 4, 0, &success);
451964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
452064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
452164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
452264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (!success)
452364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
452464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        m_inst_mode = eModeInvalid;
452564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        m_inst_pc = LLDB_INVALID_ADDRESS;
452664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
452764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return success;
452864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
452964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
4530ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t
4531ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion ()
4532ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
4533ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return m_arm_isa;
4534ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
4535ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
453664c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
453764c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ConditionPassed ()
453864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
453964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (m_inst_cpsr == 0)
454064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
454164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
454264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    const uint32_t cond = CurrentCond ();
454364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
454464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (cond == UINT32_MAX)
454564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
454664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
454764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool result = false;
454864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    switch (UnsignedBits(cond, 3, 1))
454964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
455064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break;
455164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break;
455264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break;
455364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break;
455464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break;
455564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 5:
455664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
455764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool n = (m_inst_cpsr & MASK_CPSR_N);
455864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool v = (m_inst_cpsr & MASK_CPSR_V);
455964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            result = n == v;
456064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
456164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
456264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 6:
456364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
456464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool n = (m_inst_cpsr & MASK_CPSR_N);
456564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            bool v = (m_inst_cpsr & MASK_CPSR_V);
456664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0);
456764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
456864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
456964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 7:
457064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        result = true;
457164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
457264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
457364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
457464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (cond & 1)
457564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        result = !result;
457664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return result;
457764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
457864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
45799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t
45809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::CurrentCond ()
45819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
45829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    switch (m_inst_mode)
45839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
45849ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    default:
45859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeInvalid:
45869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        break;
45879ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
45889ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeARM:
45899ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return UnsignedBits(m_inst.opcode.inst32, 31, 28);
45909ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
45919ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeThumb:
45929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
45939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        // 'cond' field of the encoding.
45949ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (m_inst.opcode_type == eOpcode16 &&
45959ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d &&
45969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f)
45979ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        {
45989ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return Bits32(m_inst.opcode.inst16, 11, 7);
45999ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
46009ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        else if (m_inst.opcode_type == eOpcode32 &&
46019ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e &&
46029ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 &&
46039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 &&
46049ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen                 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d)
46059ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        {
46069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return Bits32(m_inst.opcode.inst32, 25, 22);
46079ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
46089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
46099ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return m_it_session.GetCond();
46109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
46119ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    return UINT32_MAX;  // Return invalid value
46129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
46139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
46149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool
4615098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock()
4616098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{
4617098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
4618098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen}
4619098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen
4620098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool
4621098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock()
4622098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{
4623098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
4624098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen}
4625098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen
4626098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool
46279ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
46289ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
46299ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    addr_t target;
46309ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
4631ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    // Check the current instruction set.
4632ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    if (CurrentInstrSet() == eModeARM)
46339ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffc;
4634ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    else
46359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffe;
4636ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
46379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
463853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
463953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
464053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
46419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
46429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
46439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
46449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool
4645668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
46469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
46479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    addr_t target;
46480f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
46490f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // we want to record it and issue a WriteRegister callback so the clients
46500f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // can track the mode changes accordingly.
46510f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    bool cpsr_changed = false;
46529ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
46539ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (BitIsSet(addr, 0))
46549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
46550f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        if (CurrentInstrSet() != eModeThumb)
46560f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        {
46570f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            SelectInstrSet(eModeThumb);
46580f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            cpsr_changed = true;
46590f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        }
46609ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffe;
4661668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetMode (eModeThumb);
46629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
46639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    else if (BitIsClear(addr, 1))
46649ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
46650f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        if (CurrentInstrSet() != eModeARM)
46660f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        {
46670f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            SelectInstrSet(eModeARM);
46680f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            cpsr_changed = true;
46690f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        }
46709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffc;
4671668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetMode (eModeARM);
46729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
46739ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    else
46749ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return false; // address<1:0> == '10' => UNPREDICTABLE
46759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
46760f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    if (cpsr_changed)
46770f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    {
4678558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
46790f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            return false;
46800f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    }
46819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
468253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
468353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
468453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
46859ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
468664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
4687ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
4688ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool
4689668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
4690ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
4691ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    if (ArchVersion() >= ARMv5T)
4692668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        return BXWritePC(context, addr);
4693ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    else
4694ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        return BranchWritePC((const Context)context, addr);
4695ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
4696ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
469726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
469826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool
4699668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
470026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{
470126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
4702668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        return BXWritePC(context, addr);
470326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    else
470426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        return BranchWritePC((const Context)context, addr);
470526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen}
470626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
4707ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode
4708ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet ()
4709ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
4710ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return m_inst_mode;
4711ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
4712ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
4713ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Set the 'T' bit of our CPSR.  The m_inst_mode gets updated when the next
4714558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed.  This function has a side effect of updating
4715558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary.
4716ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool
4717ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
4718ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
4719558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen    m_new_inst_cpsr = m_inst_cpsr;
4720ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    switch (arm_or_thumb)
4721ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    {
4722ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    default:
4723ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        return false;
4724ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    eModeARM:
4725ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        // Clear the T bit.
4726558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        m_new_inst_cpsr &= ~MASK_CPSR_T;
4727ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        break;
4728ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    eModeThumb:
4729ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        // Set the T bit.
4730558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        m_new_inst_cpsr |= MASK_CPSR_T;
4731ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        break;
4732ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    }
4733ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return true;
4734ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
4735ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
4736ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for
4737ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
4738ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
4739ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool
4740ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport()
4741ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{
4742ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    return (ArchVersion() >= ARMv7);
4743ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen}
4744ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
4745bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information
4746bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions.  This status
4747bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions.
4748bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult
4749bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
4750bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{
4751bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint32_t result;
4752bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint8_t carry_out;
4753bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint8_t overflow;
4754bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
4755bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint64_t unsigned_sum = x + y + carry_in;
4756bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
4757bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
4758bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    result = UnsignedBits(unsigned_sum, 31, 0);
4759bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    carry_out = (result == unsigned_sum ? 0 : 1);
4760bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    overflow = ((int32_t)result == signed_sum ? 0 : 1);
4761bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
4762bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    AddWithCarryResult res = { result, carry_out, overflow };
4763bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    return res;
4764bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen}
4765bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
4766ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the
4767ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result.
4768ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
4769ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the
4770ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual:
4771ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
4772ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then         // Can only occur for encoding A1
4773ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     ALUWritePC(result); // setflags is always FALSE here
4774ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else
4775ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     R[d] = result;
4776ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     if setflags then
4777ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.N = result<31>;
4778ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.Z = IsZeroBit(result);
4779ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.C = carry;
4780ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         // APSR.V unchanged
4781ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
4782ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which
4783ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u.
4784ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool
478510530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
478610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t result,
478710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t Rd,
478810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  bool setflags,
478910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t carry,
479010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t overflow)
4791ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{
4792ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    if (Rd == 15)
4793ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    {
4794ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (!ALUWritePC (context, result))
4795ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
4796ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    }
4797ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    else
4798ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    {
4799ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result))
4800ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
4801ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (setflags)
480210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen            return WriteFlags (context, result, carry, overflow);
480310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    }
480410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    return true;
480510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen}
480610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
480710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the
480810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual:
480910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen//
481010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>;
481110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result);
481210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry;
481310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow
481410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen//
481510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means
481610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags.
481710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool
481810530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context,
481910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t result,
482010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t carry,
482110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t overflow)
482210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{
482310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    m_new_inst_cpsr = m_inst_cpsr;
482410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N));
482510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0);
482610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (carry != ~0u)
482710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        SetBit32(m_new_inst_cpsr, CPSR_C, carry);
482810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (overflow != ~0u)
482910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        SetBit32(m_new_inst_cpsr, CPSR_V, overflow);
483010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (m_new_inst_cpsr != m_inst_cpsr)
483110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    {
483210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
483310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen            return false;
4834ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    }
4835ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    return true;
4836ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen}
4837ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
483864c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
483964c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::EvaluateInstruction ()
484064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
4841c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    // Advance the ITSTATE bits to their values for the next instruction.
4842c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (m_inst_mode == eModeThumb && m_it_session.InITBlock())
4843c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        m_it_session.ITAdvance();
4844c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
484564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return false;
484664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
4847