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"
136b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice#include "EmulationStateARM.h"
14395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton#include "lldb/Core/ArchSpec.h"
15080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice#include "lldb/Core/Address.h"
168482dedc1d0fb4669d1ec63ec259d1cb8eaeb20fGreg Clayton#include "lldb/Core/ConstString.h"
17080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice#include "lldb/Core/PluginManager.h"
186b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice#include "lldb/Core/Stream.h"
1973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Interpreter/OptionValueArray.h"
2073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Interpreter/OptionValueDictionary.h"
21c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton#include "lldb/Symbol/UnwindPlan.h"
228482dedc1d0fb4669d1ec63ec259d1cb8eaeb20fGreg Clayton
23f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Plugins/Process/Utility/ARMDefines.h"
24f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Plugins/Process/Utility/ARMUtils.h"
25f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton#include "Utility/ARM_DWARF_Registers.h"
26f29a08f9176c1a443942c08a999763e79b911f62Greg Clayton
279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
280d91b809feae0708ec372a30d0da53959eeb062cFilipe Cabecinhas                                     // and countTrailingZeros function
2964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
3064c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonusing namespace lldb;
3164c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonusing namespace lldb_private;
3264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
33e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// Convenient macro definitions.
34b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
37f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
390e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
400e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
410e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// ITSession implementation
420e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
430e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
440e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen
45930704795c783e5bf1768a43da6f957108b40873Johnny Chen// A8.6.50
46930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
4704d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonstatic uint32_t
4804d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonCountITSize (uint32_t ITMask) {
49930704795c783e5bf1768a43da6f957108b40873Johnny Chen    // First count the trailing zeros of the IT mask.
500d91b809feae0708ec372a30d0da53959eeb062cFilipe Cabecinhas    uint32_t TZ = llvm::countTrailingZeros(ITMask);
51930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (TZ > 3)
52930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
53abfef87c9819e401cc7514fcc9ce81ba20f278adSean Callanan#ifdef LLDB_CONFIGURATION_DEBUG
54930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT Mask '0000'\n");
55abfef87c9819e401cc7514fcc9ce81ba20f278adSean Callanan#endif
56930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return 0;
57930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
58930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return (4 - TZ);
59930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
60930704795c783e5bf1768a43da6f957108b40873Johnny Chen
61930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Init ITState.  Note that at least one bit is always 1 in mask.
6204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonbool ITSession::InitIT(uint32_t bits7_0)
63930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
64930704795c783e5bf1768a43da6f957108b40873Johnny Chen    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
65930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (ITCounter == 0)
66930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
67930704795c783e5bf1768a43da6f957108b40873Johnny Chen
68930704795c783e5bf1768a43da6f957108b40873Johnny Chen    // A8.6.50 IT
69930704795c783e5bf1768a43da6f957108b40873Johnny Chen    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
70930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (FirstCond == 0xF)
71930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
72abfef87c9819e401cc7514fcc9ce81ba20f278adSean Callanan#ifdef LLDB_CONFIGURATION_DEBUG
73930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT FirstCond '1111'\n");
74abfef87c9819e401cc7514fcc9ce81ba20f278adSean Callanan#endif
75930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
76930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
77930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (FirstCond == 0xE && ITCounter != 1)
78930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
79abfef87c9819e401cc7514fcc9ce81ba20f278adSean Callanan#ifdef LLDB_CONFIGURATION_DEBUG
80930704795c783e5bf1768a43da6f957108b40873Johnny Chen        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
81abfef87c9819e401cc7514fcc9ce81ba20f278adSean Callanan#endif
82930704795c783e5bf1768a43da6f957108b40873Johnny Chen        return false;
83930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
84930704795c783e5bf1768a43da6f957108b40873Johnny Chen
85930704795c783e5bf1768a43da6f957108b40873Johnny Chen    ITState = bits7_0;
86930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return true;
87930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
88930704795c783e5bf1768a43da6f957108b40873Johnny Chen
89930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Update ITState if necessary.
90930704795c783e5bf1768a43da6f957108b40873Johnny Chenvoid ITSession::ITAdvance()
91930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
92e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton    //assert(ITCounter);
93930704795c783e5bf1768a43da6f957108b40873Johnny Chen    --ITCounter;
94930704795c783e5bf1768a43da6f957108b40873Johnny Chen    if (ITCounter == 0)
95930704795c783e5bf1768a43da6f957108b40873Johnny Chen        ITState = 0;
96930704795c783e5bf1768a43da6f957108b40873Johnny Chen    else
97930704795c783e5bf1768a43da6f957108b40873Johnny Chen    {
98930704795c783e5bf1768a43da6f957108b40873Johnny Chen        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
99930704795c783e5bf1768a43da6f957108b40873Johnny Chen        SetBits32(ITState, 4, 0, NewITState4_0);
100930704795c783e5bf1768a43da6f957108b40873Johnny Chen    }
101930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
102930704795c783e5bf1768a43da6f957108b40873Johnny Chen
103930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Return true if we're inside an IT Block.
104930704795c783e5bf1768a43da6f957108b40873Johnny Chenbool ITSession::InITBlock()
105930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
106930704795c783e5bf1768a43da6f957108b40873Johnny Chen    return ITCounter != 0;
107930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
108930704795c783e5bf1768a43da6f957108b40873Johnny Chen
109c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// Return true if we're the last instruction inside an IT Block.
110c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool ITSession::LastInITBlock()
111c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{
112c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    return ITCounter == 1;
113c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen}
114c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
115930704795c783e5bf1768a43da6f957108b40873Johnny Chen// Get condition bits for the current thumb instruction.
116930704795c783e5bf1768a43da6f957108b40873Johnny Chenuint32_t ITSession::GetCond()
117930704795c783e5bf1768a43da6f957108b40873Johnny Chen{
118c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    if (InITBlock())
119c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return Bits32(ITState, 7, 4);
120c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    else
121c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        return COND_AL;
122930704795c783e5bf1768a43da6f957108b40873Johnny Chen}
123930704795c783e5bf1768a43da6f957108b40873Johnny Chen
12464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton// ARM constants used during decoding
12564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define REG_RD          0
12664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define LDM_REGLIST     1
127e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define SP_REG          13
128e39f22d1a369866808b8739c3cec15063d806833Johnny Chen#define LR_REG          14
12964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REG          15
13064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define PC_REGLIST_BIT  0x8000
13164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
132251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv4     (1u << 0)
13364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv4T    (1u << 1)
13464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5T    (1u << 2)
13564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TE   (1u << 3)
13664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv5TEJ  (1u << 4)
137251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv6     (1u << 5)
13864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6K    (1u << 6)
13964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMv6T2   (1u << 7)
140251af6aedbd3a5b6f1a105ab9303f13b53e332ffJohnny Chen#define ARMv7     (1u << 8)
14182a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMv7S    (1u << 9)
14282a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMv8     (1u << 10)
14364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#define ARMvAll   (0xffffffffu)
14464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
14582a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
14682a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
14782a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
14882a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
14982a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
15082a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
15182a17a29a99ceef3353ac669ed44749d6106212cJason Molenda#define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
1522b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
1534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define No_VFP  0
1544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv1   (1u << 1)
1554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv2   (1u << 2)
1564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv3   (1u << 3)
1574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define AdvancedSIMD (1u << 4)
1584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
1594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
1604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
1614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#define VFPv2v3     (VFPv2 | VFPv3)
1624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
1630e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
1640e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
1650e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen// EmulateInstructionARM implementation
1660e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//
1670e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen//----------------------------------------------------------------------
1680e00af21580d7ee85e14abd518d4aa54157dcbf5Johnny Chen
1692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid
1702b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Initialize ()
1717dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen{
172080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    PluginManager::RegisterPlugin (GetPluginNameStatic (),
173080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice                                   GetPluginDescriptionStatic (),
174080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice                                   CreateInstance);
1752b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1767dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen
1772b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonvoid
1782b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::Terminate ()
17964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
180080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    PluginManager::UnregisterPlugin (CreateInstance);
1812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
1830e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString
184080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstructionARM::GetPluginNameStatic ()
185080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{
1860e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("arm");
1870e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
188080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice}
189080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
190080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticeconst char *
191080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstructionARM::GetPluginDescriptionStatic ()
192080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{
193080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    return "Emulate instructions for the ARM architecture.";
194080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice}
195080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
196080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstruction *
197888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
198080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{
199888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
200080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    {
201888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if (arch.GetTriple().getArch() == llvm::Triple::arm)
202888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        {
203102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
204888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
205888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if (emulate_insn_ap.get())
206888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                return emulate_insn_ap.release();
207888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        }
208888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
209888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        {
210102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
211888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
212888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if (emulate_insn_ap.get())
213888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                return emulate_insn_ap.release();
214888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        }
215080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    }
216080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
217080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    return NULL;
218080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice}
219080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
220080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticebool
221080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline TiceEmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
222080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{
223080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    if (arch.GetTriple().getArch () == llvm::Triple::arm)
224080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        return true;
225080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
226080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        return true;
227080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
228080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    return false;
229080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice}
230080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
231fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
232fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool
233fa17220ce8b3db56b05317fd5e69c450127f8538Caroline TiceEmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
234fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{
2359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
2369bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
2379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
238fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
239fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    uint32_t random_data = rand ();
240fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    const uint32_t addr_byte_size = GetAddressByteSize();
241fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
242cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice    if (!MemAWrite (context, address, random_data, addr_byte_size))
243fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        return false;
244fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
245fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    return true;
246fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice}
247fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
248713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
249713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool
250713c2665a27096b68f3f8956222375354f1292f8Caroline TiceEmulateInstructionARM::WriteBits32Unknown (int n)
251713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{
2529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
2539bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
2549bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
255713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
25662ff6f5a8c243ea8fb08039c71830a8138990945Johnny Chen    bool success;
257713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
258713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
259713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!success)
260713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
261713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
262713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
263713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        return false;
264713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
265713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    return true;
266713c2665a27096b68f3f8956222375354f1292f8Caroline Tice}
267713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
268c07d451bb046e47215bd73fda0235362cc6b1a47Greg Claytonbool
269c07d451bb046e47215bd73fda0235362cc6b1a47Greg ClaytonEmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
270c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton{
271c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    if (reg_kind == eRegisterKindGeneric)
272c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    {
273c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        switch (reg_num)
274c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        {
275c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
276c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
277c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
278c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
279c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
280c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            default: return false;
281c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        }
282c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    }
283c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
284c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    if (reg_kind == eRegisterKindDWARF)
285c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        return GetARMDWARFRegisterInfo(reg_num, reg_info);
286c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    return false;
287c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton}
288c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
28904d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonuint32_t
29004d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonEmulateInstructionARM::GetFramePointerRegisterNumber () const
29104d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton{
292b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    if (m_opcode_mode == eModeThumb)
293b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    {
294b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton        switch (m_arch.GetTriple().getOS())
295b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton        {
296b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            case llvm::Triple::Darwin:
297b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            case llvm::Triple::MacOSX:
298b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            case llvm::Triple::IOS:
299b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton                return 7;
300b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            default:
301b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton                break;
302b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton        }
303b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    }
304b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    return 11;
30504d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton}
30604d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton
30704d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonuint32_t
30804d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonEmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
30904d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton{
310b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    if (m_opcode_mode == eModeThumb)
311b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    {
312b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton        switch (m_arch.GetTriple().getOS())
313b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton        {
314b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            case llvm::Triple::Darwin:
315b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            case llvm::Triple::MacOSX:
316b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            case llvm::Triple::IOS:
317b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton                return dwarf_r7;
318b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton            default:
319b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton                break;
320b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton        }
321b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    }
322b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton    return dwarf_r11;
32304d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton}
32404d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton
32508c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Push Multiple Registers stores multiple registers to the stack, storing to
32608c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// consecutive memory locations ending just below the address in SP, and updates
32708c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// SP to point to the start of the stored data.
3282b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
3297bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
33064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
33164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#if 0
33264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    // ARM pseudo code...
33364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (ConditionPassed())
33464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
33564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        EncodingSpecificOperations();
33664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        NullCheckIfThumbEE(13);
33764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        address = SP - 4*BitCount(registers);
33864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
33964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        for (i = 0 to 14)
34064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
341bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if (registers<i> == '1')
34264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
34364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
34464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    MemA[address,4] = bits(32) UNKNOWN;
34564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                else
34664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    MemA[address,4] = R[i];
34764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                address = address + 4;
34864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
34964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
35064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
351bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if (registers<15> == '1') // Only possible for encoding A1 or A2
35264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            MemA[address,4] = PCStoreValue();
35364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
35464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        SP = SP - 4*BitCount(registers);
35564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
35664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton#endif
35764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
358107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    bool conditional = false;
35964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool success = false;
360107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (ConditionPassed(opcode, &conditional))
36164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
3622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
363e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
36464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (!success)
36564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            return false;
3663c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        uint32_t registers = 0;
36791d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        uint32_t Rt; // the source register
3683c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        switch (encoding) {
369aedde1c6a33b123031499800f56954adc86058f5Johnny Chen        case eEncodingT1:
370108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 7, 0);
371aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            // The M bit represents LR.
372bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (Bit32(opcode, 8))
373ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                registers |= (1u << 14);
374aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            // if BitCount(registers) < 1 then UNPREDICTABLE;
375aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            if (BitCount(registers) < 1)
376aedde1c6a33b123031499800f56954adc86058f5Johnny Chen                return false;
377aedde1c6a33b123031499800f56954adc86058f5Johnny Chen            break;
3787dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen        case eEncodingT2:
3797dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // Ignore bits 15 & 13.
380108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 15, 0) & ~0xa000;
3817dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if BitCount(registers) < 2 then UNPREDICTABLE;
3827dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            if (BitCount(registers) < 2)
3837dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen                return false;
3847dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            break;
3857dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen        case eEncodingT3:
386108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
3877dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if BadReg(t) then UNPREDICTABLE;
38891d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            if (BadReg(Rt))
3897dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen                return false;
39091d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            registers = (1u << Rt);
3917dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            break;
3923c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        case eEncodingA1:
393108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            registers = Bits32(opcode, 15, 0);
394a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // Instead of return false, let's handle the following case as well,
395a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // which amounts to pushing one reg onto the full descending stacks.
396a33d4846702ea5ee033c4e3d133548ab57ff17f3Johnny Chen            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
3973c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen            break;
3983c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        case eEncodingA2:
399108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
4007dc60e15db4643826ed68f41b5122c6075454a24Johnny Chen            // if t == 13 then UNPREDICTABLE;
40191d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            if (Rt == dwarf_sp)
4023c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen                return false;
40391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen            registers = (1u << Rt);
4043c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen            break;
405ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        default:
406ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
4073c75c76090e770bb5e47154ba4ebe3244027daa4Johnny Chen        }
408ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        addr_t sp_offset = addr_byte_size * BitCount (registers);
40964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        addr_t addr = sp - sp_offset;
41064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        uint32_t i;
41164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
4129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
413107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (conditional)
414107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextRegisterStore;
415107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
416107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextPushRegisterOnStack;
417c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo reg_info;
418c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
419c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
42064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        for (i=0; i<15; ++i)
42164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
4227c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen            if (BitIsSet (registers, i))
42364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
424c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
425c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
426e39f22d1a369866808b8739c3cec15063d806833Johnny Chen                uint32_t reg_value = ReadCoreReg(i, &success);
42764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if (!success)
42864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    return false;
429cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
43064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    return false;
43164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                addr += addr_byte_size;
43264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
43364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
43464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
4357c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen        if (BitIsSet (registers, 15))
43664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
437c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
438c9c364f939b95612bedc316b3efbedacc614c855Johnny Chen            context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
439e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            const uint32_t pc = ReadCoreReg(PC_REG, &success);
44064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            if (!success)
44164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                return false;
442e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            if (!MemAWrite (context, addr, pc, addr_byte_size))
44364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                return false;
44464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
44564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
44664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        context.type = EmulateInstruction::eContextAdjustStackPointer;
4479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
44864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
4492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
45064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            return false;
45164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
45264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return true;
45364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
45464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
455ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// Pop Multiple Registers loads multiple registers from the stack, loading from
456ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// consecutive memory locations staring at the address in SP, and updates
457ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen// SP to point just above the loaded data.
4582b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
4597bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
460ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen{
461ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#if 0
462ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    // ARM pseudo code...
463ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    if (ConditionPassed())
464ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    {
465ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
466ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        address = SP;
467ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        for i = 0 to 14
468bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
469c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
470bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then
471ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if UnalignedAllowed then
472ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                LoadWritePC(MemU[address,4]);
473ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            else
474ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                LoadWritePC(MemA[address,4]);
475bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
476bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<13> == '1' then SP = bits(32) UNKNOWN;
477ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    }
478ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen#endif
479ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
480ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    bool success = false;
481ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
482107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    bool conditional = false;
483107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (ConditionPassed(opcode, &conditional))
484107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    {
4852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
486e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
487ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        if (!success)
488ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
489ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t registers = 0;
490ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t Rt; // the destination register
491ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        switch (encoding) {
492ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT1:
493ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 7, 0);
494ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // The P bit represents PC.
495bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (Bit32(opcode, 8))
496ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                registers |= (1u << 15);
497ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(registers) < 1 then UNPREDICTABLE;
498ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (BitCount(registers) < 1)
499ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
500ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
501ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT2:
502ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // Ignore bit 13.
503ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 15, 0) & ~0x2000;
504ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
505bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
506ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
507098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
508098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
509098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                return false;
510ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
511ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingT3:
512ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            Rt = Bits32(opcode, 15, 12);
513ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
514098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 13)
515098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                return false;
516098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 15 && InITBlock() && !LastInITBlock())
517ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
518ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = (1u << Rt);
519ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
520ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingA1:
521ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = Bits32(opcode, 15, 0);
522ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // Instead of return false, let's handle the following case as well,
523ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // which amounts to popping one reg from the full descending stacks.
524ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
525ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
526bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
527098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
528ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
529ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
530ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        case eEncodingA2:
531ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            Rt = Bits32(opcode, 15, 12);
532ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            // if t == 13 then UNPREDICTABLE;
533ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (Rt == dwarf_sp)
534ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
535ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            registers = (1u << Rt);
536ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            break;
537ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        default:
538ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
539ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
540ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        addr_t sp_offset = addr_byte_size * BitCount (registers);
541ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        addr_t addr = sp;
542ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        uint32_t i, data;
543ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
5449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
545107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (conditional)
546107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextRegisterLoad;
547107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
548107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextPopRegisterOffStack;
549c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
550c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
551c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
552c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
553ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        for (i=0; i<15; ++i)
554ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        {
5557c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen            if (BitIsSet (registers, i))
556ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            {
5578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                context.SetRegisterPlusOffset (sp_reg, addr - sp);
558cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                data = MemARead(context, addr, 4, 0, &success);
559ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                if (!success)
560ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                    return false;
561061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
562ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                    return false;
563ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                addr += addr_byte_size;
564ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            }
565ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
566ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
5677c1bf922ae84a214225869dbe6a1847e891815d0Johnny Chen        if (BitIsSet (registers, 15))
568ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        {
5698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            context.SetRegisterPlusOffset (sp_reg, addr - sp);
570cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            data = MemARead(context, addr, 4, 0, &success);
571ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            if (!success)
572ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
573f3eaacfc02d0a98d3bac1eaef74ad5c1c66ccfdcJohnny Chen            // In ARMv5T and above, this is an interworking branch.
574668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
575ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen                return false;
5764a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //addr += addr_byte_size;
577ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        }
578ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
579ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
5809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
581ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
5822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
583ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen            return false;
584ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    }
585ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen    return true;
586ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen}
587ef85e9162b61fa40ff9d3c9e32476e53cc94aac1Johnny Chen
5885b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// Set r7 or ip to point to saved value residing within the stack.
589bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen// ADD (SP plus immediate)
5902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
5917bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
592bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen{
593bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#if 0
594bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    // ARM pseudo code...
595bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    if (ConditionPassed())
596bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    {
597bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        EncodingSpecificOperations();
598bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
599bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        if d == 15 then
600bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
601bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        else
602bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            R[d] = result;
603bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            if setflags then
604bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.N = result<31>;
605bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.Z = IsZeroBit(result);
606bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.C = carry;
607bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen                APSR.V = overflow;
608bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    }
609bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen#endif
610bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
611bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    bool success = false;
612bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
6137bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
614bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    {
615e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
616bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        if (!success)
617bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
618bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        uint32_t Rd; // the destination register
619bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        uint32_t imm32;
620bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        switch (encoding) {
621bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        case eEncodingT1:
622bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            Rd = 7;
623bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
624bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            break;
625bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        case eEncodingA1:
626bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            Rd = Bits32(opcode, 15, 12);
627bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
628bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            break;
629bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        default:
630bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
631bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        }
632bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        addr_t sp_offset = imm32;
633bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen        addr_t addr = sp + sp_offset; // a pointer to the stack area
634bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
6359bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
63675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        context.type = eContextSetFramePointer;
637c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
638c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
6399bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (sp_reg, sp_offset);
640bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
6412b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
642bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen            return false;
643bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    }
644bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen    return true;
645bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen}
646bcec3afc23f922f87f60f4d216b0dfb5c209c67dJohnny Chen
6472ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// Set r7 or ip to the current stack pointer.
6482ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen// MOV (register)
6492b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
6507bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
6512ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen{
6522ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#if 0
6532ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    // ARM pseudo code...
6542ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    if (ConditionPassed())
6552ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    {
6562ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        EncodingSpecificOperations();
6572ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        result = R[m];
6582ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        if d == 15 then
6592ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
6602ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        else
6612ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            R[d] = result;
6622ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            if setflags then
6632ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                APSR.N = result<31>;
6642ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                APSR.Z = IsZeroBit(result);
6652ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                // APSR.C unchanged
6662ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen                // APSR.V unchanged
6672ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    }
6682ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen#endif
6692ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
6702ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    bool success = false;
6712ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
6727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
6732ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    {
674e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
6752ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        if (!success)
6762ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
6772ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        uint32_t Rd; // the destination register
6782ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        switch (encoding) {
6792ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        case eEncodingT1:
6802ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            Rd = 7;
6812ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            break;
6822ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        case eEncodingA1:
6832ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            Rd = 12;
6842ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            break;
6852ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        default:
6862ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
6872ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen        }
6889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
6899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
69004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        if (Rd == GetFramePointerRegisterNumber())
69104d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton            context.type = EmulateInstruction::eContextSetFramePointer;
69204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        else
69304d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton            context.type = EmulateInstruction::eContextRegisterPlusOffset;
694c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
695c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
6969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (sp_reg, 0);
6972ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
6982b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
6992ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen            return false;
7002ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    }
7012ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen    return true;
7022ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen}
7032ccad833be6e4122ee94efd0f5918a34afb02f9eJohnny Chen
7041c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// Move from high register (r8-r15) to low register (r0-r7).
7051c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen// MOV (register)
7062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
7077bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
7081c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen{
7097bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateMOVRdRm (opcode, encoding);
710338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen}
711338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen
712338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// Move from register to register.
713338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen// MOV (register)
714338bf54a49633d90f3c5e808847470901f25dee9Johnny Chenbool
7157bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
716338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen{
7171c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#if 0
7181c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    // ARM pseudo code...
7191c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    if (ConditionPassed())
7201c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    {
7211c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        EncodingSpecificOperations();
7221c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        result = R[m];
7231c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        if d == 15 then
7241c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
7251c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        else
7261c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            R[d] = result;
7271c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            if setflags then
7281c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                APSR.N = result<31>;
7291c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                APSR.Z = IsZeroBit(result);
7301c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                // APSR.C unchanged
7311c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen                // APSR.V unchanged
7321c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    }
7331c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen#endif
7341c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
7351c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    bool success = false;
7361c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
7377bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
7381c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    {
7391c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        uint32_t Rm; // the source register
7401c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        uint32_t Rd; // the destination register
741338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        bool setflags;
7421c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        switch (encoding) {
7431c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        case eEncodingT1:
7447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
7451c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            Rm = Bits32(opcode, 6, 3);
746338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            setflags = false;
7477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rd == 15 && InITBlock() && !LastInITBlock())
7487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
749338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            break;
750338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        case eEncodingT2:
7517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 2, 0);
752338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            Rm = Bits32(opcode, 5, 3);
753338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen            setflags = true;
7547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (InITBlock())
7557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
7561c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            break;
7577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT3:
7587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
7597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 3, 0);
7607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
7617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
7627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (setflags && (BadReg(Rd) || BadReg(Rm)))
7637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
7647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
7657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
7667c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
767ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
76801d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen        case eEncodingA1:
76901d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen            Rd = Bits32(opcode, 15, 12);
77001d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen            Rm = Bits32(opcode, 3, 0);
77101d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen            setflags = BitIsSet(opcode, 20);
7721f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
77301d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
77401d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen            if (Rd == 15 && setflags)
7751f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
77601d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen            break;
7771c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        default:
7781c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            return false;
7791c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        }
7807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t result = ReadCoreReg(Rm, &success);
7811c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        if (!success)
7821c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen            return false;
7831c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
7841c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen        // The context specifies that Rm is to be moved into Rd.
7859bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
7862b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice        context.type = EmulateInstruction::eContextRegisterLoad;
787c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
788c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
7892b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice        context.SetRegister (dwarf_reg);
790ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
79110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
792ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
7931c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    }
7941c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen    return true;
7951c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen}
7961c13b62188b2ae5d1f2acce539f1034d71189516Johnny Chen
797357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// Move (immediate) writes an immediate value to the destination register.  It
798357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// can optionally update the condition flags based on the value.
799357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen// MOV (immediate)
800357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chenbool
8017bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
802357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen{
803357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#if 0
804357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    // ARM pseudo code...
805357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    if (ConditionPassed())
806357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    {
807357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        EncodingSpecificOperations();
808357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        result = imm32;
809357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
810357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
811357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        else
812357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            R[d] = result;
813357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen            if setflags then
814357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.N = result<31>;
815357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.Z = IsZeroBit(result);
816357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                APSR.C = carry;
817357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen                // APSR.V unchanged
818357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    }
819357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen#endif
820357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
8217bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
822357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    {
823357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t Rd; // the destination register
824357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm32; // the immediate value to be written to Rd
82565f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen        uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
82665f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen                            // for setflags == false, this value is a don't care
82765f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen                            // initialized to 0 to silence the static analyzer
828357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        bool setflags;
829357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        switch (encoding) {
83089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            case eEncodingT1:
83189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                Rd = Bits32(opcode, 10, 8);
83289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                setflags = !InITBlock();
83389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
83489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                carry = APSR_C;
83589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
83689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                break;
83789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
83889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            case eEncodingT2:
83989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                Rd = Bits32(opcode, 11, 8);
84089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                setflags = BitIsSet(opcode, 20);
84189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
84289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                if (BadReg(Rd))
84389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                  return false;
84489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
84589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                break;
84689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
84789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            case eEncodingT3:
84889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            {
84989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
85089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                Rd = Bits32 (opcode, 11, 8);
85189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                setflags = false;
85289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                uint32_t imm4 = Bits32 (opcode, 19, 16);
85389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                uint32_t imm3 = Bits32 (opcode, 14, 12);
85489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                uint32_t i = Bit32 (opcode, 26);
85589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                uint32_t imm8 = Bits32 (opcode, 7, 0);
85689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
85789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
85889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                // if BadReg(d) then UNPREDICTABLE;
85989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                if (BadReg (Rd))
86089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                    return false;
86189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            }
86289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                break;
86389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
86489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            case eEncodingA1:
865061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
86689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                Rd = Bits32 (opcode, 15, 12);
86789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                setflags = BitIsSet (opcode, 20);
86889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
8691f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
870061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
8711f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                if ((Rd == 15) && setflags)
8721f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                    return EmulateSUBSPcLrEtc (opcode, encoding);
87389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
87489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                break;
87589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
87689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            case eEncodingA2:
87789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            {
87889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
87989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                Rd = Bits32 (opcode, 15, 12);
88089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                setflags = false;
88189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                uint32_t imm4 = Bits32 (opcode, 19, 16);
88289c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                uint32_t imm12 = Bits32 (opcode, 11, 0);
88389c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                imm32 = (imm4 << 12) | imm12;
88489c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
88589c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                // if d == 15 then UNPREDICTABLE;
88689c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                if (Rd == 15)
88789c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                    return false;
88889c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            }
88989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice                break;
89089c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice
89189c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice            default:
8929798cfcb34cd66965fb3ff58e60a14309534b29eJohnny Chen                return false;
893357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        }
894357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t result = imm32;
895357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
896357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        // The context specifies that an immediate is to be moved into Rd.
8979bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
8989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
8999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
900ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
90110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
902ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
903357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    }
904357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen    return true;
905357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen}
906357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen
9075c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
9085c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
9095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// unsigned values.
9105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice//
9115c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
9125c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice// limited to only a few forms of the instruction.
9135c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Ticebool
9147bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
9155c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice{
9165c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#if 0
9175c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice    if ConditionPassed() then
9185c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        EncodingSpecificOperations();
9195c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
9205c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
9215c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        result = operand1 * operand2;
9225c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        R[d] = result<31:0>;
9235c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        if setflags then
9245c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            APSR.N = result<31>;
9255c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            APSR.Z = IsZeroBit(result);
9265c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            if ArchVersion() == 4 then
9275c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                APSR.C = bit UNKNOWN;
9285c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            // else APSR.C unchanged
9295c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            // APSR.V always unchanged
9305c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice#endif
9315c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
9335c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice    {
9345c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        uint32_t d;
9355c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        uint32_t n;
9365c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        uint32_t m;
9375c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        bool setflags;
9385c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9395c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // EncodingSpecificOperations();
9405c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        switch (encoding)
9415c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        {
9425c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            case eEncodingT1:
9435c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
9445c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                d = Bits32 (opcode, 2, 0);
9455c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                n = Bits32 (opcode, 5, 3);
9465c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                m = Bits32 (opcode, 2, 0);
9475c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                setflags = !InITBlock();
9485c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9495c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
9505c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                if ((ArchVersion() < ARMv6) && (d == n))
9515c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                    return false;
9525c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9535c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                break;
9545c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9555c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            case eEncodingT2:
9565c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
9575c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                d = Bits32 (opcode, 11, 8);
9585c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                n = Bits32 (opcode, 19, 16);
9595c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                m = Bits32 (opcode, 3, 0);
9605c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                setflags = false;
9615c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9625c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
9635c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                if (BadReg (d) || BadReg (n) || BadReg (m))
9645c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                    return false;
9655c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9665c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                break;
9675c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9685c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            case eEncodingA1:
969bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
9705c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                d = Bits32 (opcode, 19, 16);
9715c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                n = Bits32 (opcode, 3, 0);
9725c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                m = Bits32 (opcode, 11, 8);
9735c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                setflags = BitIsSet (opcode, 20);
9745c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9755c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
9765c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                if ((d == 15) ||  (n == 15) || (m == 15))
9775c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                    return false;
9785c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9795c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
9805c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                if ((ArchVersion() < ARMv6) && (d == n))
9815c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                    return false;
9825c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9835c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                break;
9845c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9855c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            default:
9865c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                return false;
9875c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        }
9887bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton
9897bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
9907bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton
9915c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
9925c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
9935c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        if (!success)
9945c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            return false;
9955c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
9965c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
9975c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
9985c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        if (!success)
9995c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            return false;
10005c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
10015c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // result = operand1 * operand2;
10025c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        uint64_t result = operand1 * operand2;
10035c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
10045c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // R[d] = result<31:0>;
1005c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo op1_reg;
1006c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo op2_reg;
1007c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1008c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
10095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
10105c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        EmulateInstruction::Context context;
1011c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
10125c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
10135c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
10145c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
10155c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            return false;
10165c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
10175c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // if setflags then
10185c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        if (setflags)
10195c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        {
10205c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            // APSR.N = result<31>;
10215c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            // APSR.Z = IsZeroBit(result);
1022b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            m_new_inst_cpsr = m_opcode_cpsr;
10235c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
10245c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1025b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            if (m_new_inst_cpsr != m_opcode_cpsr)
10265c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            {
10275c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
10285c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                    return false;
10295c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            }
10305c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
10315c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice            // if ArchVersion() == 4 then
10325c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice                // APSR.C = bit UNKNOWN;
10335c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        }
10345c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice    }
10355c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice    return true;
10365c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice}
10375c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice
1038d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1039d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the value.
104028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chenbool
10417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
104228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen{
104328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#if 0
104428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    // ARM pseudo code...
104528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    if (ConditionPassed())
104628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    {
104728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        EncodingSpecificOperations();
104828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        result = NOT(imm32);
104928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
105028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
105128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        else
105228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            R[d] = result;
105328070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen            if setflags then
105428070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.N = result<31>;
105528070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.Z = IsZeroBit(result);
105628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                APSR.C = carry;
105728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen                // APSR.V unchanged
105828070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen    }
105928070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen#endif
106033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen
10617bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
106233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    {
106333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        uint32_t Rd; // the destination register
1064357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1065357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
106633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        bool setflags;
106733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        switch (encoding) {
106833bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        case eEncodingT1:
106933bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            Rd = Bits32(opcode, 11, 8);
107033bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            setflags = BitIsSet(opcode, 20);
1071d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
107233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            break;
107333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        case eEncodingA1:
107433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            Rd = Bits32(opcode, 15, 12);
107533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            setflags = BitIsSet(opcode, 20);
1076d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
10771f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
1078d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1079d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if (Rd == 15 && setflags)
10801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
108133bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            break;
108233bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        default:
108333bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen            return false;
108433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        }
108533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        uint32_t result = ~imm32;
108633bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen
108733bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
10889bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
10899bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextImmediate;
10909bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetNoArgs ();
1091ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
109210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1093ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
109433bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    }
109533bf6ab6b5771f1bae225edcc2115772d9d041acJohnny Chen    return true;
109628070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen}
109728070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen
1098d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1099d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen// It can optionally update the condition flags based on the result.
1100d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chenbool
11017bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1102d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen{
1103d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#if 0
1104d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    // ARM pseudo code...
1105d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    if (ConditionPassed())
1106d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    {
1107d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        EncodingSpecificOperations();
1108d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1109d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        result = NOT(shifted);
1110d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
1111d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
1112d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        else
1113d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            R[d] = result;
1114d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if setflags then
1115d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                APSR.N = result<31>;
1116d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                APSR.Z = IsZeroBit(result);
1117d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                APSR.C = carry;
1118d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                // APSR.V unchanged
1119d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    }
1120d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen#endif
1121d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
11227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
1123d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    {
1124d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t Rm; // the source register
1125d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t Rd; // the destination register
1126d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        ARM_ShifterType shift_t;
1127d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
1128d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        bool setflags;
1129d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t carry; // the carry bit after the shift operation
1130d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        switch (encoding) {
1131d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        case eEncodingT1:
1132d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rd = Bits32(opcode, 2, 0);
1133d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rm = Bits32(opcode, 5, 3);
1134d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            setflags = !InITBlock();
1135d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            shift_t = SRType_LSL;
1136d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            shift_n = 0;
1137d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            if (InITBlock())
1138d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                return false;
1139d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            break;
1140d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        case eEncodingT2:
1141d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rd = Bits32(opcode, 11, 8);
1142d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rm = Bits32(opcode, 3, 0);
1143d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            setflags = BitIsSet(opcode, 20);
11443dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1145d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1146ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            if (BadReg(Rd) || BadReg(Rm))
1147d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen                return false;
1148ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
1149d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        case eEncodingA1:
1150d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rd = Bits32(opcode, 15, 12);
1151d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            Rm = Bits32(opcode, 3, 0);
1152d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            setflags = BitIsSet(opcode, 20);
11533dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
1154d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            break;
1155d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        default:
1156d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            return false;
1157d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        }
11587bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
1159d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t value = ReadCoreReg(Rm, &success);
1160d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        if (!success)
1161d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            return false;
1162d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
1163a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1164a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
1165a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
1166d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        uint32_t result = ~shifted;
1167d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
1168d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // The context specifies that an immediate is to be moved into Rd.
1169d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        EmulateInstruction::Context context;
1170d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
1171d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        context.SetNoArgs ();
1172d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
1173d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1174d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen            return false;
1175d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    }
1176d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen    return true;
1177d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen}
1178d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen
1179788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1180788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen// LDR (literal)
11812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
11827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1183788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen{
1184788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#if 0
1185788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    // ARM pseudo code...
1186788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    if (ConditionPassed())
1187788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    {
1188788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1189788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        base = Align(PC,4);
1190788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        address = if add then (base + imm32) else (base - imm32);
1191788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        data = MemU[address,4];
1192788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if t == 15 then
1193bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1194bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        elsif UnalignedSupport() || address<1:0> = '00' then
1195788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            R[t] = data;
1196788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        else // Can only apply before ARMv7
1197788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            if CurrentInstrSet() == InstrSet_ARM then
1198788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen                R[t] = ROR(data, 8*UInt(address<1:0>));
1199788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            else
1200788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen                R[t] = bits(32) UNKNOWN;
1201788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    }
1202788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen#endif
1203788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
12047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
1205788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    {
12067bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
1207e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1208788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if (!success)
1209788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
1210809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen
1211809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen        // PC relative immediate load context
12129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
12139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1214c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo pc_reg;
1215c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
12169bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (pc_reg, 0);
12179bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
1218c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        uint32_t Rt;    // the destination register
1219788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        uint32_t imm32; // immediate offset from the PC
1220c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        bool add;       // +imm32 or -imm32?
1221c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        addr_t base;    // the base address
1222c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        addr_t address; // the PC relative address
1223788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        uint32_t data;  // the literal data value from the PC relative load
1224788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        switch (encoding) {
1225788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        case eEncodingT1:
1226c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            Rt = Bits32(opcode, 10, 8);
1227788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1228c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            add = true;
1229c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            break;
1230c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        case eEncodingT2:
1231c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            Rt = Bits32(opcode, 15, 12);
1232c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1233c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            add = BitIsSet(opcode, 23);
1234098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (Rt == 15 && InITBlock() && !LastInITBlock())
1235c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
1236788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            break;
1237788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        default:
1238788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen            return false;
1239788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        }
1240c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
1241e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        base = Align(pc, 4);
1242c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (add)
1243c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            address = base + imm32;
1244c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else
1245c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            address = base - imm32;
1246e39f22d1a369866808b8739c3cec15063d806833Johnny Chen
1247e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        context.SetRegisterPlusOffset(pc_reg, address - base);
1248cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        data = MemURead(context, address, 4, 0, &success);
1249788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen        if (!success)
1250809742eb9fcff84b07b72f06838f927d4fccfa49Johnny Chen            return false;
1251c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
1252c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        if (Rt == 15)
1253c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        {
1254c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            if (Bits32(address, 1, 0) == 0)
1255c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            {
1256c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                // In ARMv5T and above, this is an interworking branch.
1257668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen                if (!LoadWritePC(context, data))
1258c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                    return false;
1259c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            }
1260c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            else
1261c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
1262c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        }
1263c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1264c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        {
1265c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1266c9de910d61f0471d18fced716fc10681ef432010Johnny Chen                return false;
1267c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        }
1268c9de910d61f0471d18fced716fc10681ef432010Johnny Chen        else // We don't handle ARM for now.
1269c9de910d61f0471d18fced716fc10681ef432010Johnny Chen            return false;
1270c9de910d61f0471d18fced716fc10681ef432010Johnny Chen
1271788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    }
1272788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen    return true;
1273788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen}
1274788e05550dfd52699d427bb44c9716f320d2adacJohnny Chen
12755b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// An add operation to adjust the SP.
1276fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// ADD (SP plus immediate)
12772b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
12787bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1279fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen{
1280fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#if 0
1281fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    // ARM pseudo code...
1282fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    if (ConditionPassed())
1283fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    {
1284fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        EncodingSpecificOperations();
1285bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1286fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        if d == 15 then // Can only occur for ARM encoding
1287fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
1288fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        else
1289fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            R[d] = result;
1290fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            if setflags then
1291fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.N = result<31>;
1292fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.Z = IsZeroBit(result);
1293fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.C = carry;
1294fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen                APSR.V = overflow;
1295fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    }
1296fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen#endif
1297fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
1298fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    bool success = false;
1299fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
13007bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
1301fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    {
1302e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
1303fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        if (!success)
1304fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen            return false;
1305fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        uint32_t imm32; // the immediate operand
1306e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        uint32_t d;
13074a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton        //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1308e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        switch (encoding)
1309e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        {
1310e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice            case eEncodingT1:
1311bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1312e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                d = Bits32 (opcode, 10, 8);
1313e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                imm32 = (Bits32 (opcode, 7, 0) << 2);
1314e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice
1315e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                break;
1316e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice
1317e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice            case eEncodingT2:
1318bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1319e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                d = 13;
1320e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1321e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice
1322e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                break;
1323e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice
1324e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice            default:
1325e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                return false;
1326fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        }
1327fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        addr_t sp_offset = imm32;
1328fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1329fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
13309bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
13319bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAdjustStackPointer;
1332c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
1333c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1334080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1335fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
1336e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        if (d == 15)
1337e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        {
1338e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice            if (!ALUWritePC (context, addr))
1339e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                return false;
1340e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        }
1341e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        else
1342e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        {
1343e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1344e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice                return false;
13454a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton
13464a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            // Add this back if/when support eEncodingT3 eEncodingA1
13474a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //if (setflags)
13484a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //{
13494a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //    APSR.N = result<31>;
13504a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //    APSR.Z = IsZeroBit(result);
13514a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //    APSR.C = carry;
13524a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //    APSR.V = overflow;
13534a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            //}
1354e221288aff8b6b97fb39a121f62233eae791295eCaroline Tice        }
1355fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    }
1356fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen    return true;
1357fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen}
1358fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen
1359fdd179e6f94128924473c3cce1123ad1c749015dJohnny Chen// An add operation to adjust the SP.
13605b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen// ADD (SP plus register)
13612b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
13627bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
13635b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen{
13645b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#if 0
13655b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    // ARM pseudo code...
13665b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    if (ConditionPassed())
13675b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    {
13685b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        EncodingSpecificOperations();
13695b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1370bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
13715b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if d == 15 then
13725b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
13735b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        else
13745b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            R[d] = result;
13755b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            if setflags then
13765b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.N = result<31>;
13775b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.Z = IsZeroBit(result);
13785b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.C = carry;
13795b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen                APSR.V = overflow;
13805b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    }
13815b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen#endif
13825b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
13835b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    bool success = false;
13845b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
13857bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
13865b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    {
1387e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
13885b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if (!success)
13895b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
13905b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        uint32_t Rm; // the second operand
13915b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        switch (encoding) {
13925b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        case eEncodingT2:
13935b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            Rm = Bits32(opcode, 6, 3);
13945b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            break;
13955b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        default:
13965b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
13975b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        }
1398e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        int32_t reg_value = ReadCoreReg(Rm, &success);
13995b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        if (!success)
14005b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
14015b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
14025b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
14035b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
14049bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
1405c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
1406c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
1407c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1408c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
1409c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo other_reg;
1410c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1411080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        context.SetRegisterRegisterOperands (sp_reg, other_reg);
14125b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
14132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
14145b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen            return false;
14155b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    }
14165b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen    return true;
14175b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen}
14185b442b7326d1c96eaf93290bb8285635579eb38fJohnny Chen
14199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
14209b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// at a PC-relative address, and changes instruction set from ARM to Thumb, or
14219b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// from Thumb to ARM.
14229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (immediate)
14239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool
14247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
14259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{
14269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0
14279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    // ARM pseudo code...
14289b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
14299b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
14309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        EncodingSpecificOperations();
14319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if CurrentInstrSet() == InstrSet_ARM then
14329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = PC - 4;
14339b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
14349b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = PC<31:1> : '1';
14359b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if targetInstrSet == InstrSet_ARM then
14369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            targetAddress = Align(PC,4) + imm32;
14379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
14389b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            targetAddress = PC + imm32;
14399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        SelectInstrSet(targetInstrSet);
14409b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        BranchWritePC(targetAddress);
14419b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
14429b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif
14439b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
14447bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    bool success = true;
14459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
14467bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
14479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
14489bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
14499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1450e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
14519b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!success)
14529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
145353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t lr; // next instruction address
145453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t target; // target address
14559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        int32_t imm32; // PC-relative offset
14569b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        switch (encoding) {
1457d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen        case eEncodingT1:
1458d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            {
1459e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = pc | 1u; // return address
1460bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
1461d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t imm10 = Bits32(opcode, 25, 16);
1462bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1463bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
1464d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
1465d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t I1 = !(J1 ^ S);
1466d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            uint32_t I2 = !(J2 ^ S);
146753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1468d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1469e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
1470c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1471098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1472ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
1473d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            break;
1474d6c13f00a467e7c9357c9fbb4375a0b77d20c6a9Johnny Chen            }
14759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingT2:
14769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            {
1477e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = pc | 1u; // return address
1478bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
14799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t imm10H = Bits32(opcode, 25, 16);
1480bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
1481bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
14829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t imm10L = Bits32(opcode, 10, 1);
14839b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t I1 = !(J1 ^ S);
14849b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            uint32_t I2 = !(J2 ^ S);
148553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
14869b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
1487e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = Align(pc, 4) + imm32;
1488c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1489098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1490ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
14919b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
14929b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            }
1493c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen        case eEncodingA1:
14942b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice            lr = pc - 4; // return address
1495c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1496e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = Align(pc, 4) + imm32;
1497c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1498c47d0caf319bef8b7263b60366ad62606a2ccb20Johnny Chen            break;
14999b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingA2:
15002b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice            lr = pc - 4; // return address
15019b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1502e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
1503c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
15049b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
15059b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        default:
15069b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
15079b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        }
15089b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
15099b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
15109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!BranchWritePC(context, target))
15119b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
15129b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
15139b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    return true;
15149b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen}
15159b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
15169b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// Branch with Link and Exchange (register) calls a subroutine at an address and
15179b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// instruction set specified by a register.
15189b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen// BLX (register)
15199b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chenbool
15207bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
15219b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen{
15229b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#if 0
15239b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    // ARM pseudo code...
15249b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    if (ConditionPassed())
15259b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
15269b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        EncodingSpecificOperations();
15279b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        target = R[m];
15289b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if CurrentInstrSet() == InstrSet_ARM then
15299b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            next_instr_addr = PC - 4;
15309b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            LR = next_instr_addr;
15319b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        else
15329b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            next_instr_addr = PC - 2;
1533bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            LR = next_instr_addr<31:1> : '1';
15349b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        BXWritePC(target);
15359b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
15369b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen#endif
15379b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
15389b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    bool success = false;
15399b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
15407bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
15419b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    {
15429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
15439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1544e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
15459b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        addr_t lr; // next instruction address
15469b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!success)
15479b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
15489b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        uint32_t Rm; // the register with the target address
15499b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        switch (encoding) {
15509b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingT1:
1551e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = (pc - 2) | 1u; // return address
15529b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            Rm = Bits32(opcode, 6, 3);
15539b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            // if m == 15 then UNPREDICTABLE;
15549b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            if (Rm == 15)
15559b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen                return false;
1556098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1557ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
15589b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            break;
15599b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        case eEncodingA1:
1560e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            lr = pc - 4; // return address
15619b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            Rm = Bits32(opcode, 3, 0);
15629b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            // if m == 15 then UNPREDICTABLE;
15639b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            if (Rm == 15)
15649b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen                return false;
1565b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
15669b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        default:
15679b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
15689b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        }
1569e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        addr_t target = ReadCoreReg (Rm, &success);
1570ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        if (!success)
1571ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1572c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
1573c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
15749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegister (dwarf_reg);
15759b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
15769b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
1577668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        if (!BXWritePC(context, target))
15789b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen            return false;
15799b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    }
15809b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen    return true;
15819b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen}
15829b8d783409b5b80af2cf129c45cbc39c9544cccaJohnny Chen
1583ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1584ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chenbool
15857bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1586ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen{
1587ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#if 0
1588ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    // ARM pseudo code...
1589ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    if (ConditionPassed())
1590ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    {
1591ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        EncodingSpecificOperations();
1592ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        BXWritePC(R[m]);
1593ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    }
1594ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen#endif
1595ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
15967bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
1597ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    {
15989bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
15999bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1600ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        uint32_t Rm; // the register with the target address
1601ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        switch (encoding) {
1602ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        case eEncodingT1:
1603ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            Rm = Bits32(opcode, 6, 3);
1604098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen            if (InITBlock() && !LastInITBlock())
1605ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen                return false;
1606ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            break;
1607ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        case eEncodingA1:
1608ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            Rm = Bits32(opcode, 3, 0);
1609ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            break;
1610ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        default:
1611ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1612ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        }
16137bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
1614e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        addr_t target = ReadCoreReg (Rm, &success);
1615ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        if (!success)
1616ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1617c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
1618c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
1619c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1620668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        context.SetRegister (dwarf_reg);
1621668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        if (!BXWritePC(context, target))
1622ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen            return false;
1623ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    }
1624ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen    return true;
1625ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen}
1626ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen
162759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
162859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// address and instruction set specified by a register as though it were a BX instruction.
162959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen//
163059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen// TODO: Emulate Jazelle architecture?
163159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
163259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chenbool
16337bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
163459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen{
163559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#if 0
163659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    // ARM pseudo code...
163759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    if (ConditionPassed())
163859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    {
163959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        EncodingSpecificOperations();
1640bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
164159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            BXWritePC(R[m]);
164259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        else
164359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            if JazelleAcceptsExecution() then
164459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen                SwitchToJazelleExecution();
164559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            else
164659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen                SUBARCHITECTURE_DEFINED handler call;
164759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    }
164859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen#endif
164959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen
16507bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
165159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    {
165259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        EmulateInstruction::Context context;
165359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
165459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        uint32_t Rm; // the register with the target address
165559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        switch (encoding) {
165659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        case eEncodingT1:
165759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            Rm = Bits32(opcode, 19, 16);
165859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            if (BadReg(Rm))
165959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen                return false;
166059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            if (InITBlock() && !LastInITBlock())
166159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen                return false;
166259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            break;
166359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        case eEncodingA1:
166459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            Rm = Bits32(opcode, 3, 0);
166559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            if (Rm == 15)
166659e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen                return false;
166759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            break;
166859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        default:
166959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            return false;
167059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        }
16717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
167259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        addr_t target = ReadCoreReg (Rm, &success);
167359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        if (!success)
167459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            return false;
167559e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen
1676c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
1677c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
167859e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        context.SetRegister (dwarf_reg);
167959e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        if (!BXWritePC(context, target))
168059e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen            return false;
168159e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    }
168259e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen    return true;
168359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen}
168459e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen
16850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set r7 to point to some ip offset.
16860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (immediate)
16872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
16887bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
16890d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{
16900d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0
16910d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    // ARM pseudo code...
16920d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (ConditionPassed())
16930d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
16940d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        EncodingSpecificOperations();
1695bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
16960d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if d == 15 then // Can only occur for ARM encoding
16970d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
16980d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        else
16990d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            R[d] = result;
17000d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            if setflags then
17010d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.N = result<31>;
17020d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.Z = IsZeroBit(result);
17030d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.C = carry;
17040d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.V = overflow;
17050d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
17060d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif
17070d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
17090d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
17107bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
1711e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t ip = ReadCoreReg (12, &success);
17120d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if (!success)
17130d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
17140d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        uint32_t imm32;
17150d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        switch (encoding) {
17160d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        case eEncodingA1:
17170d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
17180d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            break;
17190d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        default:
17200d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
17210d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        }
17220d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t ip_offset = imm32;
17230d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t addr = ip - ip_offset; // the adjusted ip value
17240d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
17269bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1727c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
1728c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
17299bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
17300d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
17320d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
17330d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
17340d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    return true;
17350d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen}
17360d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17370d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// Set ip to point to some stack offset.
17380d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen// SUB (SP minus immediate)
17392b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
17407bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
17410d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen{
17420d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#if 0
17430d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    // ARM pseudo code...
17440d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    if (ConditionPassed())
17450d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
17460d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        EncodingSpecificOperations();
1747bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
17480d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if d == 15 then // Can only occur for ARM encoding
17490d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
17500d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        else
17510d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            R[d] = result;
17520d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            if setflags then
17530d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.N = result<31>;
17540d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.Z = IsZeroBit(result);
17550d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.C = carry;
17560d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen                APSR.V = overflow;
17570d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
17580d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen#endif
17590d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
17610d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    {
17627bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        bool success = false;
1763e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
17640d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        if (!success)
17650d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
17660d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        uint32_t imm32;
17670d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        switch (encoding) {
17680d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        case eEncodingA1:
17690d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
17700d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            break;
17710d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        default:
17720d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
17730d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        }
17740d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t sp_offset = imm32;
17750d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
17760d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
17789bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1779c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
1780c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
17819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
17820d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
17832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
17840d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen            return false;
17850d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    }
17860d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen    return true;
17870d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen}
17880d0148e3b359e7be24ae00cb484503241f71f47cJohnny Chen
1789c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// This instruction subtracts an immediate value from the SP value, and writes
1790c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// the result to the destination register.
1791c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen//
1792c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
17932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
17947bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
17954c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen{
17964c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#if 0
17974c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    // ARM pseudo code...
17984c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    if (ConditionPassed())
17994c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    {
18004c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        EncodingSpecificOperations();
1801bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
180215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if d == 15 then        // Can only occur for ARM encoding
1803799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen           ALUWritePC(result); // setflags is always FALSE here
18044c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        else
18054c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            R[d] = result;
18064c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            if setflags then
18074c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.N = result<31>;
18084c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.Z = IsZeroBit(result);
18094c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.C = carry;
18104c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen                APSR.V = overflow;
18114c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    }
18124c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen#endif
18134c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
18144c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    bool success = false;
18157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
18164c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    {
1817e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
18184c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        if (!success)
18194c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
1820c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen
1821c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        uint32_t Rd;
1822c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        bool setflags;
18234c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        uint32_t imm32;
18244c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        switch (encoding) {
1825e44550232e767c692c25eb933fd88d7b857a6d55Johnny Chen        case eEncodingT1:
1826c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            Rd = 13;
1827c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            setflags = false;
1828a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1829ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
183060c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen        case eEncodingT2:
1831c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            Rd = Bits32(opcode, 11, 8);
1832c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            setflags = BitIsSet(opcode, 20);
183360c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1834c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            if (Rd == 15 && setflags)
18357bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateCMPImm(opcode, eEncodingT2);
1836c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            if (Rd == 15 && !setflags)
1837c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen                return false;
183860c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            break;
183960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen        case eEncodingT3:
1840c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            Rd = Bits32(opcode, 11, 8);
1841c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            setflags = false;
184260c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
184315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            if (Rd == 15)
184415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen                return false;
184560c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            break;
18464c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        case eEncodingA1:
1847c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            Rd = Bits32(opcode, 15, 12);
1848c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            setflags = BitIsSet(opcode, 20);
184960c0d627a506752b3b9ef5c0b11f1640b739b9ffJohnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
18501f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
185115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
185215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            if (Rd == 15 && setflags)
18531f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
18544c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            break;
18554c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        default:
18564c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
18574c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen        }
1858c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1859c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen
18609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
1861c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        if (Rd == 13)
1862c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        {
18632b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
18642b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice                                     // value gets passed down to context.SetImmediateSigned.
1865c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            context.type = EmulateInstruction::eContextAdjustStackPointer;
18662b03ed8c697040c107d9c0c7d810fcb2e5c7fb8dCaroline Tice            context.SetImmediateSigned (-imm64); // the stack pointer offset
1867c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        }
1868c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        else
1869c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        {
1870c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            context.type = EmulateInstruction::eContextImmediate;
1871c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen            context.SetNoArgs ();
1872c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        }
1873c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen
1874c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
18754c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen            return false;
18764c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    }
18774c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen    return true;
18784c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen}
18794c0e0bc24aa6a4dc2c18a6f6d01b9217dee5c4bfJohnny Chen
188008c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// A store operation to the stack that also updates the SP.
18812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
18827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1883ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen{
1884ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#if 0
1885ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    // ARM pseudo code...
1886ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    if (ConditionPassed())
1887ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    {
1888ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        EncodingSpecificOperations();
1889ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1890ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        address = if index then offset_addr else R[n];
1891ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1892ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        if wback then R[n] = offset_addr;
1893ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    }
1894ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen#endif
1895ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
1896107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    bool conditional = false;
1897ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    bool success = false;
1898107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (ConditionPassed(opcode, &conditional))
1899ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    {
19002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
1901e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
1902ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        if (!success)
1903ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
190491d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        uint32_t Rt; // the source register
1905ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        uint32_t imm12;
19063e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
19073e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice
19083e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        bool index;
19093e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        bool add;
19103e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        bool wback;
1911ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        switch (encoding) {
1912ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        case eEncodingA1:
1913108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            Rt = Bits32(opcode, 15, 12);
1914108d5aaa1379f154e459d82aa482b4f2ddf134c7Johnny Chen            imm12 = Bits32(opcode, 11, 0);
19153e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            Rn = Bits32 (opcode, 19, 16);
19163e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice
19173e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
19183e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice                return false;
19193e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice
19203e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            index = BitIsSet (opcode, 24);
19213e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            add = BitIsSet (opcode, 23);
19223e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
19233e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice
19243e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            if (wback && ((Rn == 15) || (Rn == Rt)))
19253e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice                return false;
1926ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            break;
1927ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        default:
1928ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            return false;
1929ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
19303e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        addr_t offset_addr;
19313e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        if (add)
19323e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            offset_addr = sp + imm12;
19333e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        else
19343e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            offset_addr = sp - imm12;
19353e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice
19363e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        addr_t addr;
19373e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        if (index)
19383e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            addr = offset_addr;
19393e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        else
19403e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            addr = sp;
1941ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
19429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
1943107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (conditional)
1944107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextRegisterStore;
1945107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
1946107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextPushRegisterOnStack;
1947c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
1948b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton        RegisterInfo dwarf_reg;
1949b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton
1950c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1951b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1952b9e8f6e7a374d9313f89193e90ae41ef91712e5bGreg Clayton        context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
195391d998659e5d38aeebb3b8ebe2fb596907bd0548Johnny Chen        if (Rt != 15)
1954ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        {
1955e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            uint32_t reg_value = ReadCoreReg(Rt, &success);
1956ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            if (!success)
1957ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1958cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1959ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1960ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1961ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        else
1962ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        {
1963e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1964ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen            if (!success)
1965ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
19668d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            if (!MemUWrite (context, addr, pc, addr_byte_size))
1967ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen                return false;
1968ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen        }
1969ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
19703e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice
19713e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        if (wback)
19723e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        {
19733e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            context.type = EmulateInstruction::eContextAdjustStackPointer;
19743e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            context.SetImmediateSigned (addr - sp);
19753e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
19763e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice                return false;
19773e4079716c15760dfd6efc62391d5c1da713cef6Caroline Tice        }
1978ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    }
1979ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen    return true;
1980ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen}
1981ce1ca773286c85b4c2a81b99aaa42f46b47e64c2Johnny Chen
198208c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// Vector Push stores multiple extension registers to the stack.
198308c25e855749d94d89ff162a30ff46c9a2911aceJohnny Chen// It also updates SP to point to the start of the stored data.
19842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Claytonbool
19857bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1986799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen{
1987799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#if 0
1988799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    // ARM pseudo code...
1989799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    if (ConditionPassed())
1990799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    {
1991799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1992799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        address = SP - imm32;
1993799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        SP = SP - imm32;
1994799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        if single_regs then
1995799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            for r = 0 to regs-1
1996799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address,4] = S[d+r]; address = address+4;
1997799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        else
1998799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            for r = 0 to regs-1
1999799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                // Store as two word-aligned words in the correct order for current endianness.
2000799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2001799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2002799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                address = address+8;
2003799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    }
2004799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen#endif
2005799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
2006799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    bool success = false;
2007107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    bool conditional = false;
2008107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (ConditionPassed(opcode, &conditional))
2009799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    {
20102b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        const uint32_t addr_byte_size = GetAddressByteSize();
2011e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
2012799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        if (!success)
2013799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
2014799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        bool single_regs;
2015587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2016799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t imm32; // stack offset
2017799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t regs;  // number of registers
2018799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        switch (encoding) {
2019799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingT1:
2020799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingA1:
2021799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            single_regs = false;
2022bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2023799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2024799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // If UInt(imm8) is odd, see "FSTMX".
2025799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            regs = Bits32(opcode, 7, 0) / 2;
2026799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2027799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
2028799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
2029799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            break;
2030799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingT2:
2031799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        case eEncodingA2:
2032799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            single_regs = true;
2033bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2034799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2035799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            regs = Bits32(opcode, 7, 0);
2036799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2037799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
2038799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
2039799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            break;
2040799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        default:
2041799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
2042799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        }
2043799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2044799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2045799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        addr_t sp_offset = imm32;
2046799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        addr_t addr = sp - sp_offset;
2047799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        uint32_t i;
2048799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
20499bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
2050107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (conditional)
2051107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextRegisterStore;
2052107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
2053107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextPushRegisterOnStack;
2054c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
2055c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
2056c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2057bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        for (i=0; i<regs; ++i)
2058799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        {
2059c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2060bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2061799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            // uint64_t to accommodate 64-bit registers.
2062061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2063799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            if (!success)
2064799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
2065cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2066799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen                return false;
2067799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            addr += reg_byte_size;
2068799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        }
2069799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
2070799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
20719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (-sp_offset);
2072799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
20732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2074799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen            return false;
2075799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    }
2076799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen    return true;
2077799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen}
2078799dfd0f6946879ef5035f131c0f3f04145a68ceJohnny Chen
2079587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// Vector Pop loads multiple extension registers from the stack.
2080587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen// It also updates SP to point just above the loaded data.
2081587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chenbool
20827bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2083587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen{
2084587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#if 0
2085587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    // ARM pseudo code...
2086587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    if (ConditionPassed())
2087587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    {
2088587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2089587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        address = SP;
2090587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        SP = SP + imm32;
2091587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if single_regs then
2092587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            for r = 0 to regs-1
2093587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                S[d+r] = MemA[address,4]; address = address+4;
2094587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        else
2095587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            for r = 0 to regs-1
2096587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2097587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                // Combine the word-aligned words in the correct order for current endianness.
2098587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2099587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    }
2100587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen#endif
2101587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
2102587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    bool success = false;
2103107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    bool conditional = false;
2104107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (ConditionPassed(opcode, &conditional))
2105587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    {
2106587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        const uint32_t addr_byte_size = GetAddressByteSize();
2107e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const addr_t sp = ReadCoreReg (SP_REG, &success);
2108587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if (!success)
2109587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
2110587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        bool single_regs;
2111587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2112587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t imm32; // stack offset
2113587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t regs;  // number of registers
2114587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        switch (encoding) {
2115587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingT1:
2116587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingA1:
2117587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            single_regs = false;
2118bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2119587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2120587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // If UInt(imm8) is odd, see "FLDMX".
2121587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            regs = Bits32(opcode, 7, 0) / 2;
2122587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2123587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
2124587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
2125587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            break;
2126587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingT2:
2127587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        case eEncodingA2:
2128587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            single_regs = true;
2129bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2130587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2131587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            regs = Bits32(opcode, 7, 0);
2132587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2133587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (regs == 0 || regs > 16 || (d + regs) > 32)
2134587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
2135587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            break;
2136587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        default:
2137587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
2138587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        }
2139587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2140587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2141587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        addr_t sp_offset = imm32;
2142587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        addr_t addr = sp;
2143587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint32_t i;
2144587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        uint64_t data; // uint64_t to accomodate 64-bit registers.
2145587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
21469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
2147107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (conditional)
2148107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextRegisterLoad;
2149107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
2150107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            context.type = EmulateInstruction::eContextPopRegisterOffStack;
2151c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
2152c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
2153c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2154bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        for (i=0; i<regs; ++i)
2155587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        {
2156c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2157bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2158cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            data = MemARead(context, addr, reg_byte_size, 0, &success);
2159587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            if (!success)
2160587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
2161061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2162587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen                return false;
2163587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            addr += reg_byte_size;
2164587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        }
2165587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
2166587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        context.type = EmulateInstruction::eContextAdjustStackPointer;
21679bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetImmediateSigned (sp_offset);
2168587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
2169587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2170587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen            return false;
2171587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    }
2172587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen    return true;
2173587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen}
2174587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen
2175b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen// SVC (previously SWI)
2176b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chenbool
21777bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2178b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen{
2179b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#if 0
2180b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    // ARM pseudo code...
2181b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    if (ConditionPassed())
2182b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    {
2183b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        EncodingSpecificOperations();
2184b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        CallSupervisor();
2185b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    }
2186b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen#endif
2187b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
2188b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    bool success = false;
2189b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
21907bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
2191b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    {
2192e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2193b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        addr_t lr; // next instruction address
2194b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        if (!success)
2195b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
2196b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        uint32_t imm32; // the immediate constant
2197b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        uint32_t mode;  // ARM or Thumb mode
2198b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        switch (encoding) {
2199b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        case eEncodingT1:
2200b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            lr = (pc + 2) | 1u; // return address
2201b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            imm32 = Bits32(opcode, 7, 0);
2202b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            mode = eModeThumb;
2203b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
2204b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        case eEncodingA1:
2205b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            lr = pc + 4; // return address
2206b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            imm32 = Bits32(opcode, 23, 0);
2207b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            mode = eModeARM;
2208b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            break;
2209b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        default:
2210b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
2211b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        }
22129bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
22139bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
22149bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextSupervisorCall;
2215c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.SetISAAndImmediate (mode, imm32);
2216b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2217b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen            return false;
2218b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    }
2219b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen    return true;
2220b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen}
2221b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
2222c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen// If Then makes up to four following instructions (the IT block) conditional.
2223c315f860b343cf4a143f43c7d570d151989abb46Johnny Chenbool
22247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2225c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen{
2226c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#if 0
2227c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    // ARM pseudo code...
2228c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    EncodingSpecificOperations();
2229c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    ITSTATE.IT<7:0> = firstcond:mask;
2230c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen#endif
2231c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
2232c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    m_it_session.InitIT(Bits32(opcode, 7, 0));
2233c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    return true;
2234c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen}
2235c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
223604d397c5e251eaa5f520dbe6381d2a82303350e1Greg Claytonbool
223704d397c5e251eaa5f520dbe6381d2a82303350e1Greg ClaytonEmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
223804d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton{
223904d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton    // NOP, nothing to do...
224004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton    return true;
224104d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton}
224204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton
22433b620b38cd170c20ea607585021ab2ab50286943Johnny Chen// Branch causes a branch to a target address.
22443b620b38cd170c20ea607585021ab2ab50286943Johnny Chenbool
22457bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
22463b620b38cd170c20ea607585021ab2ab50286943Johnny Chen{
22473b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#if 0
22483b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    // ARM pseudo code...
22493b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    if (ConditionPassed())
22503b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    {
22513b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        EncodingSpecificOperations();
22523b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        BranchWritePC(PC + imm32);
22533b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    }
22543b620b38cd170c20ea607585021ab2ab50286943Johnny Chen#endif
22553b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
22563b620b38cd170c20ea607585021ab2ab50286943Johnny Chen    bool success = false;
22573b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
22587bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
22599ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
22609bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
22619bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2262e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        const uint32_t pc = ReadCoreReg(PC_REG, &success);
22639ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!success)
22649ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
226553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        addr_t target; // target address
22669ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        int32_t imm32; // PC-relative offset
22679ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        switch (encoding) {
22689ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT1:
22699ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
22709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2271e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
2272c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
22739ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
22749ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT2:
22759ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2276e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
2277c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
22789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
22799ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT3:
22809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
22819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            {
2282bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
22839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm6 = Bits32(opcode, 21, 16);
2284bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
2285bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
22869ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
228753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
22889ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<21>(imm21);
2289e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
2290c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
22919ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
22929ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            }
22939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingT4:
22949ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            {
2295bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t S = Bit32(opcode, 26);
22969ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm10 = Bits32(opcode, 25, 16);
2297bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J1 = Bit32(opcode, 13);
2298bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            uint32_t J2 = Bit32(opcode, 11);
22999ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t imm11 = Bits32(opcode, 10, 0);
23009ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t I1 = !(J1 ^ S);
23019ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            uint32_t I2 = !(J2 ^ S);
230253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
23039ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<25>(imm25);
2304e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
2305c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
23069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
23079ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            }
23089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        case eEncodingA1:
23099ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2310e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            target = pc + imm32;
2311c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
23129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            break;
23139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        default:
23149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
23159ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
23169ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        if (!BranchWritePC(context, target))
23179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen            return false;
23189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
23199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    return true;
23203b620b38cd170c20ea607585021ab2ab50286943Johnny Chen}
23213b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
232253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
232353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
232453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen// CBNZ, CBZ
232553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chenbool
23267bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
232753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen{
232853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#if 0
232953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    // ARM pseudo code...
233053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    EncodingSpecificOperations();
233153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if nonzero ^ IsZero(R[n]) then
233253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        BranchWritePC(PC + imm32);
233353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen#endif
233453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
233553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    bool success = false;
233653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
233753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    // Read the register value from the operand register Rn.
2338e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
233953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
234053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
234153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
23429bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
23439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2344e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    const uint32_t pc = ReadCoreReg(PC_REG, &success);
234553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (!success)
234653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
234753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
234853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    addr_t target;  // target address
234953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    uint32_t imm32; // PC-relative offset to branch forward
235053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    bool nonzero;
235153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    switch (encoding) {
235253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    case eEncodingT1:
2353bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
235453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        nonzero = BitIsSet(opcode, 11);
2355e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        target = pc + imm32;
2356c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
235753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        break;
235853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    default:
235953ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
236053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    }
236153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    if (nonzero ^ (reg_val == 0))
236253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        if (!BranchWritePC(context, target))
236353ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen            return false;
236453ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
236553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
236653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen}
236753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
236860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
236960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table.
237060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the byte returned from the table.
237160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen//
237260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
237360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// A base register provides a pointer to the table, and a second register supplies an index into the table.
237460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// The branch length is twice the value of the halfword returned from the table.
237560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen// TBB, TBH
237660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chenbool
23777bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
237860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen{
237960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#if 0
238060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // ARM pseudo code...
238160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
238260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if is_tbh then
238360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
238460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    else
238560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        halfwords = UInt(MemU[R[n]+R[m], 1]);
238660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    BranchWritePC(PC + 2*halfwords);
238760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen#endif
238860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
238960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    bool success = false;
239060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
239160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
239260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
239360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    bool is_tbh;     // true if table branch halfword
239460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    switch (encoding) {
239560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    case eEncodingT1:
239660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rn = Bits32(opcode, 19, 16);
239760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        Rm = Bits32(opcode, 3, 0);
239860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        is_tbh = BitIsSet(opcode, 4);
239960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        if (Rn == 13 || BadReg(Rm))
240060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen            return false;
240160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        if (InITBlock() && !LastInITBlock())
240260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen            return false;
240360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        break;
240460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    default:
240560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
240660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    }
240760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
240860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // Read the address of the table from the operand register Rn.
240960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // The PC can be used, in which case the table immediately follows this instruction.
2410e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t base = ReadCoreReg(Rm, &success);
241160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
241260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
241360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
241460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // the table index
2415e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t index = ReadCoreReg(Rm, &success);
241660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
241760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
241860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
241960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // the offsetted table address
242060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    addr_t addr = base + (is_tbh ? index*2 : index);
242160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
242260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // PC-relative offset to branch forward
242360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    EmulateInstruction::Context context;
242460299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2425104c8b69863f229033d616245f56243ca51f1de9Johnny Chen    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
242660299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
242760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
242860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
2429e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    const uint32_t pc = ReadCoreReg(PC_REG, &success);
243060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!success)
243160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
243260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
243360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    // target address
2434e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    addr_t target = pc + offset;
243560299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2436c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
243760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
243860299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    if (!BranchWritePC(context, target))
243960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        return false;
244060299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
244160299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen    return true;
244260299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen}
244360299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen
2444dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2445dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice// It can optionally update the condition flags based on the result.
2446dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Ticebool
24477bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2448dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice{
2449dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#if 0
2450dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice    if ConditionPassed() then
2451dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        EncodingSpecificOperations();
2452bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2453dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        R[d] = result;
2454dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        if setflags then
2455dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            APSR.N = result<31>;
2456dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            APSR.Z = IsZeroBit(result);
2457dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            APSR.C = carry;
2458dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            APSR.V = overflow;
2459dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice#endif
2460dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2461dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice    bool success = false;
2462dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
24637bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
2464dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice    {
2465dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        uint32_t d;
2466dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        uint32_t n;
2467dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        bool setflags;
2468dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        uint32_t imm32;
2469dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        uint32_t carry_out;
2470dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2471dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        //EncodingSpecificOperations();
2472dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        switch (encoding)
2473dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        {
2474dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            case eEncodingT1:
2475dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2476dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                d = Bits32 (opcode, 2, 0);
2477dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                n = Bits32 (opcode, 5, 3);
2478dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                setflags = !InITBlock();
2479dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                imm32 = Bits32 (opcode, 8,6);
2480dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2481dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                break;
2482dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2483dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            case eEncodingT2:
2484dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2485dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                d = Bits32 (opcode, 10, 8);
2486dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                n = Bits32 (opcode, 10, 8);
2487dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                setflags = !InITBlock();
2488dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
2489dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2490dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                break;
2491dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2492dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            case eEncodingT3:
2493bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2494bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1101' then SEE ADD (SP plus immediate);
2495bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2496dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                d = Bits32 (opcode, 11, 8);
2497dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                n = Bits32 (opcode, 19, 16);
2498dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                setflags = BitIsSet (opcode, 20);
2499dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2500dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2501dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2502dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                if (BadReg (d) || (n == 15))
2503dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                    return false;
2504dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2505dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                break;
2506dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2507dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            case eEncodingT4:
2508dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            {
2509bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE ADR;
2510bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1101' then SEE ADD (SP plus immediate);
2511dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2512dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                d = Bits32 (opcode, 11, 8);
2513dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                n = Bits32 (opcode, 19, 16);
2514dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                setflags = false;
2515dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                uint32_t i = Bit32 (opcode, 26);
2516dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                uint32_t imm3 = Bits32 (opcode, 14, 12);
2517dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                uint32_t imm8 = Bits32 (opcode, 7, 0);
2518dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                imm32 = (i << 11) | (imm3 << 8) | imm8;
2519dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2520dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                // if BadReg(d) then UNPREDICTABLE;
2521dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                if (BadReg (d))
2522dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                    return false;
2523dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2524dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                break;
2525dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            }
2526dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            default:
2527dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice                return false;
2528dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        }
2529dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2530dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2531dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        if (!success)
2532dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            return false;
2533dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2534bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2535dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2536dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2537c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo reg_n;
2538c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2539dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2540dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        EmulateInstruction::Context context;
2541c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
2542dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        context.SetRegisterPlusOffset (reg_n, imm32);
2543dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2544dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        //R[d] = result;
2545dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        //if setflags then
2546dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            //APSR.N = result<31>;
2547dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            //APSR.Z = IsZeroBit(result);
2548dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            //APSR.C = carry;
2549dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            //APSR.V = overflow;
2550dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2551dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice            return false;
2552dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
2553dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice    }
2554dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice    return true;
2555dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice}
2556dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice
25578fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// This instruction adds an immediate value to a register value, and writes the result to the destination
25588fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen// register.  It can optionally update the condition flags based on the result.
25598fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chenbool
25607bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
25618fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen{
25628fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#if 0
25638fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    // ARM pseudo code...
25648fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    if ConditionPassed() then
25658fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        EncodingSpecificOperations();
25668fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
25678fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        if d == 15 then
25688fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
25698fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        else
25708fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            R[d] = result;
25718fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            if setflags then
25728fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.N = result<31>;
25738fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.Z = IsZeroBit(result);
25748fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.C = carry;
25758fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen                APSR.V = overflow;
25768fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen#endif
25778fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
25788fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    bool success = false;
25798fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
25807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
25818fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    {
25828fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        uint32_t Rd, Rn;
25838fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
25848fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        bool setflags;
25858fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        switch (encoding)
25868fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        {
25878fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        case eEncodingA1:
25888fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rd = Bits32(opcode, 15, 12);
25898fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rn = Bits32(opcode, 19, 16);
25908fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            setflags = BitIsSet(opcode, 20);
25918fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
25928fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            break;
25938fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        default:
25948fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            return false;
25958fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        }
25968fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
25978fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        // Read the first operand.
2598157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
25998fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        if (!success)
26008fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            return false;
26018fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
26028fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
26038fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
26048fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        EmulateInstruction::Context context;
2605c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
2606c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
2607c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2608080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, imm32);
26098fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
26108fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
26118fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            return false;
26128fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    }
26138fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen    return true;
26148fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen}
26158fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen
2616d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// This instruction adds a register value and an optionally-shifted register value, and writes the result
2617d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen// to the destination register. It can optionally update the condition flags based on the result.
261826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool
26197bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
262026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{
262126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#if 0
262226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    // ARM pseudo code...
262326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if ConditionPassed() then
262426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        EncodingSpecificOperations();
262526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
262626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
262726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if d == 15 then
262826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
262926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        else
263026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            R[d] = result;
263126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            if setflags then
263226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.N = result<31>;
263326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.Z = IsZeroBit(result);
263426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.C = carry;
263526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                APSR.V = overflow;
263626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen#endif
263726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
263826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    bool success = false;
263926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
26407bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
264126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    {
264226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        uint32_t Rd, Rn, Rm;
2643d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        ARM_ShifterType shift_t;
2644d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
2645ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        bool setflags;
264626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        switch (encoding)
264726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        {
2648d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen        case eEncodingT1:
2649d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rd = Bits32(opcode, 2, 0);
2650d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rn = Bits32(opcode, 5, 3);
2651d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            Rm = Bits32(opcode, 8, 6);
2652d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            setflags = !InITBlock();
2653d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_t = SRType_LSL;
2654d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_n = 0;
2655ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
265626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        case eEncodingT2:
2657bd599907c7c6203e02123d825d1df017ce58f653Johnny Chen            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
265826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            Rm = Bits32(opcode, 6, 3);
2659ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            setflags = false;
2660d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_t = SRType_LSL;
2661d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            shift_n = 0;
266226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            if (Rn == 15 && Rm == 15)
266326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen                return false;
2664d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen            if (Rd == 15 && InITBlock() && !LastInITBlock())
2665d761dcf991d66ab1d686f874270ba3c8cc9ff28cJohnny Chen                return false;
266626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            break;
26678fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        case eEncodingA1:
26688fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rd = Bits32(opcode, 15, 12);
26698fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rn = Bits32(opcode, 19, 16);
26708fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            Rm = Bits32(opcode, 3, 0);
26718fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            setflags = BitIsSet(opcode, 20);
26723dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
26738fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen            break;
267426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        default:
267526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
267626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        }
267726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
267826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Read the first operand.
2679157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
268026863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (!success)
268126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
268226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
268326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Read the second operand.
2684157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
268526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        if (!success)
268626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen            return false;
268726863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
2688a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2689a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
2690a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
26918fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
26929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
26939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
2694c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
2695c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo op1_reg;
2696c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo op2_reg;
2697c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2698c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
26998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2700ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
270110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2702ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
270326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    }
270426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    return true;
270526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen}
270626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
270734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (immediate) adds a register value and an immediate value.
270834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
270934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool
27107bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
271134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{
271234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0
271334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // ARM pseudo code...
271434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if ConditionPassed() then
271534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        EncodingSpecificOperations();
271634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
271734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.N = result<31>;
271834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.Z = IsZeroBit(result);
271934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.C = carry;
272034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.V = overflow;
272134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif
272234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
272334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    bool success = false;
272434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
272534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t Rn; // the first operand
272634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t imm32; // the immediate value to be compared with
272734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    switch (encoding) {
272834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingT1:
2729078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        Rn = Bits32(opcode, 19, 16);
2730078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2731078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        if (Rn == 15)
2732078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen            return false;
2733ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
273434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
273534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
273634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
273734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        break;
273834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    default:
273934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
274034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    }
274134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // Read the register value from the operand register Rn.
274234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
274334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
274434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
274534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
2746078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
274734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
274834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    EmulateInstruction::Context context;
274934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
275034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.SetNoArgs ();
275134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
275234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
275334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
275434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    return true;
275534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen}
275634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
275734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare Negative (register) adds a register value and an optionally-shifted register value.
275834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
275934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chenbool
27607bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
276134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen{
276234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#if 0
276334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // ARM pseudo code...
276434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if ConditionPassed() then
276534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        EncodingSpecificOperations();
276634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
276734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
276834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.N = result<31>;
276934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.Z = IsZeroBit(result);
277034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.C = carry;
277134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        APSR.V = overflow;
277234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen#endif
277334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
277434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    bool success = false;
277534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
277634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t Rn; // the first operand
277734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t Rm; // the second operand
277834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    ARM_ShifterType shift_t;
277934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
278034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    switch (encoding) {
278134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingT1:
278234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 2, 0);
278334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 5, 3);
278434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
278534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
278634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        break;
278734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingT2:
2788078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        Rn = Bits32(opcode, 19, 16);
2789078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        Rm = Bits32(opcode, 3, 0);
27903dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2791078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2792078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        if (Rn == 15 || BadReg(Rm))
279334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen            return false;
279434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        break;
279534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
279634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
279734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 3, 0);
27983dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen        shift_n = DecodeImmShiftARM(opcode, shift_t);
2799ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
280034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    default:
280134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
280234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    }
280334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // Read the register value from register Rn.
280434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
280534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
280634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
280734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
280834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    // Read the register value from register Rm.
280934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
281034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!success)
281134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
281234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
2813a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2814a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    if (!success)
2815a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        return false;
2816078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
281734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
281834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    EmulateInstruction::Context context;
281934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
282034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    context.SetNoArgs();
282134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
282234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        return false;
282334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
282434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    return true;
282534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen}
282634075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
282734075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (immediate) subtracts an immediate value from a register value.
282834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
2829d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chenbool
28307bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2831d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen{
2832d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#if 0
2833d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    // ARM pseudo code...
2834d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if ConditionPassed() then
2835d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        EncodingSpecificOperations();
2836d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2837d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.N = result<31>;
2838d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.Z = IsZeroBit(result);
2839d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.C = carry;
2840d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        APSR.V = overflow;
2841d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen#endif
2842d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2843d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    bool success = false;
2844d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
2845d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t Rn; // the first operand
2846d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    uint32_t imm32; // the immediate value to be compared with
2847d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    switch (encoding) {
2848d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    case eEncodingT1:
2849d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        Rn = Bits32(opcode, 10, 8);
2850d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        imm32 = Bits32(opcode, 7, 0);
2851ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
2852078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen    case eEncodingT2:
2853078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        Rn = Bits32(opcode, 19, 16);
2854078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2855078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen        if (Rn == 15)
2856078fbc6d0bcce29a296a1afa91dae01bccf3cff5Johnny Chen            return false;
2857ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
285834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
285934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
286034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2861d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        break;
2862d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    default:
2863d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2864d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    }
2865d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    // Read the register value from the operand register Rn.
2866e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
2867d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    if (!success)
2868d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen        return false;
2869d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
287010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
287110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
28729bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
28739bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextImmediate;
28749bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs ();
287510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
287610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        return false;
287710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
2878d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen    return true;
2879d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen}
2880d4dc4444e124b290cbe30cdaade7e97161fa47c8Johnny Chen
288134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// Compare (register) subtracts an optionally-shifted register value from a register value.
288234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen// It updates the condition flags based on the result, and discards the result.
2883e4a4d301f3a06539098608749c55afaec063fca9Johnny Chenbool
28847bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2885e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen{
2886e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#if 0
2887e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // ARM pseudo code...
2888e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if ConditionPassed() then
2889e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        EncodingSpecificOperations();
2890e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2891e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2892e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.N = result<31>;
2893e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.Z = IsZeroBit(result);
2894e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.C = carry;
2895e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        APSR.V = overflow;
2896e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen#endif
2897e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2898e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    bool success = false;
2899e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2900e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t Rn; // the first operand
2901e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    uint32_t Rm; // the second operand
290234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    ARM_ShifterType shift_t;
290334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
2904e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    switch (encoding) {
2905e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    case eEncodingT1:
2906e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rn = Bits32(opcode, 2, 0);
2907e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rm = Bits32(opcode, 5, 3);
290834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
290934075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
2910e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        break;
2911e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    case eEncodingT2:
2912e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2913e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        Rm = Bits32(opcode, 6, 3);
291434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_t = SRType_LSL;
291534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        shift_n = 0;
2916e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        if (Rn < 8 && Rm < 8)
2917e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen            return false;
2918e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        if (Rn == 15 || Rm == 15)
2919e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen            return false;
2920e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        break;
292134075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    case eEncodingA1:
292234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rn = Bits32(opcode, 19, 16);
292334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        Rm = Bits32(opcode, 3, 0);
29243dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen        shift_n = DecodeImmShiftARM(opcode, shift_t);
2925ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
2926e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    default:
2927e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2928e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    }
2929e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // Read the register value from register Rn.
293034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
2931e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2932e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
293334075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen
2934e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    // Read the register value from register Rm.
293534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
2936e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    if (!success)
2937e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen        return false;
2938e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
2939a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2940a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    if (!success)
2941a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        return false;
294234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
294310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
29449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    EmulateInstruction::Context context;
29459bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.type = EmulateInstruction::eContextImmediate;
29469bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice    context.SetNoArgs();
294710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
294810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        return false;
294910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
2950e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen    return true;
2951e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen}
2952e4a4d301f3a06539098608749c55afaec063fca9Johnny Chen
295382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
295482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register.  It can
295582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen// optionally update the condition flags based on the result.
295682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chenbool
29577bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
295882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen{
295982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#if 0
296082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    // ARM pseudo code...
296182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    if ConditionPassed() then
296282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        EncodingSpecificOperations();
296382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
296482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
296582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
296682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        else
296782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            R[d] = result;
296882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            if setflags then
296982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.N = result<31>;
297082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.Z = IsZeroBit(result);
297182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                APSR.C = carry;
297282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                // APSR.V unchanged
297382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen#endif
297482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
29757bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftImm (opcode, encoding, SRType_ASR);
297641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
297741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
297841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
297941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in copies of its sign bit, and writes the result to the destination register.
298041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update
298141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// the condition flags based on the result.
298241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
29837bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
298441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
298541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
298641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
298741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
298841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
298941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
299041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
299141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
299241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
299341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
299441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
299541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
299641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
299741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
299841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
29997bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftReg (opcode, encoding, SRType_ASR);
300041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
300141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
300241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
300341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  It can optionally
300441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result.
300541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
30067bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
300741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
300841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
300941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
301041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
301141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
301241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
301341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
301441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
301541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        else
301641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            R[d] = result;
301741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            if setflags then
301841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.N = result<31>;
301941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.Z = IsZeroBit(result);
302041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.C = carry;
302141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                // APSR.V unchanged
302241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
302341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
30247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftImm (opcode, encoding, SRType_LSL);
302541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
302641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
302741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Left (register) shifts a register value left by a variable number of bits,
302841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  The variable number
302941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition
303041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result.
303141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
30327bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
303341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
303441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
303541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
303641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
303741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
303841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
303941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
304041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
304141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
304241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
304341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
304441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
304541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
304641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
304741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
30487bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftReg (opcode, encoding, SRType_LSL);
304941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
305041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
305141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
305241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  It can optionally
305341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// update the condition flags based on the result.
305441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
30557bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
305641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
305741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
305841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
305941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
306041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
306141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
306241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
306341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
306441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        else
306541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            R[d] = result;
306641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            if setflags then
306741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.N = result<31>;
306841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.Z = IsZeroBit(result);
306941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                APSR.C = carry;
307041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen                // APSR.V unchanged
307141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
307241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
30737bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftImm (opcode, encoding, SRType_LSR);
307441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
307541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
307641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// Logical Shift Right (register) shifts a register value right by a variable number of bits,
307741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// shifting in zeros, and writes the result to the destination register.  The variable number
307841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// of bits is read from the bottom byte of a register. It can optionally update the condition
307941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen// flags based on the result.
308041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
30817bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
308241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
308341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#if 0
308441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    // ARM pseudo code...
308541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen    if ConditionPassed() then
308641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        EncodingSpecificOperations();
308741a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        shift_n = UInt(R[m]<7:0>);
308841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
308941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        R[d] = result;
309041a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen        if setflags then
309141a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.N = result<31>;
309241a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.Z = IsZeroBit(result);
309341a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            APSR.C = carry;
309441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen            // APSR.V unchanged
309541a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen#endif
309641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
30977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftReg (opcode, encoding, SRType_LSR);
309841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen}
309941a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
3100eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3101eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3102eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// It can optionally update the condition flags based on the result.
3103eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
31047bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3105eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
3106eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
3107eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
3108eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
3109eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
3110eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3111eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
3112eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
3113eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        else
3114eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            R[d] = result;
3115eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            if setflags then
3116eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.N = result<31>;
3117eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.Z = IsZeroBit(result);
3118eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.C = carry;
3119eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                // APSR.V unchanged
3120eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
3121eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
31227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3123eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
3124eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
3125eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3126eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3127eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3128eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// flags based on the result.
3129eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
31307bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3131eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
3132eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
3133eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
3134eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
3135eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
3136eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        shift_n = UInt(R[m]<7:0>);
3137eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3138eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        R[d] = result;
3139eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if setflags then
3140eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.N = result<31>;
3141eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.Z = IsZeroBit(result);
3142eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            APSR.C = carry;
3143eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // APSR.V unchanged
3144eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
3145eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
31467bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3147eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
3148eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
3149eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3150eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// with the carry flag shifted into bit [31].
3151eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen//
3152eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// RRX can optionally update the condition flags based on the result.
3153eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen// In that case, bit [0] is shifted into the carry flag.
3154eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chenbool
31557bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3156eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen{
3157eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#if 0
3158eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    // ARM pseudo code...
3159eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen    if ConditionPassed() then
3160eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        EncodingSpecificOperations();
3161eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3162eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
3163eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
3164eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        else
3165eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            R[d] = result;
3166eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            if setflags then
3167eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.N = result<31>;
3168eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.Z = IsZeroBit(result);
3169eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                APSR.C = carry;
3170eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen                // APSR.V unchanged
3171eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen#endif
3172eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
31737bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3174eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen}
3175eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
317641a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chenbool
31777bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
317841a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen{
3179e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton//    assert(shift_type == SRType_ASR
3180e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton//           || shift_type == SRType_LSL
3181e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton//           || shift_type == SRType_LSR
3182e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton//           || shift_type == SRType_ROR
3183e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton//           || shift_type == SRType_RRX);
318441a0a15df85a0d4b428c13dff8606a064f5d8dfeJohnny Chen
318582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    bool success = false;
318682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
31877bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
318882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    {
3189e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rd;    // the destination register
3190e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rm;    // the first operand register
3191e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t imm5;  // encoding for the shift amount
319282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        uint32_t carry; // the carry bit after the shift operation
319382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        bool setflags;
3194eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
3195eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // Special case handling!
3196eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // A8.6.139 ROR (immediate) -- Encoding T1
31977bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        ARMEncoding use_encoding = encoding;
31987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3199eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        {
3200eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3201eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // have the same decoding of bit fields as the other Thumb2 shift operations.
32027bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            use_encoding = eEncodingT2;
3203eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        }
3204eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
32057bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        switch (use_encoding) {
320682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingT1:
3207eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // Due to the above special case handling!
32086cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen            if (shift_type == SRType_ROR)
32096cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen                return false;
3210eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
321182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 2, 0);
321282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 5, 3);
321382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = !InITBlock();
321482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 10, 6);
321582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
321682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingT2:
3217eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            // A8.6.141 RRX
32186cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen            // There's no imm form of RRX instructions.
32196cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen            if (shift_type == SRType_RRX)
32206cc6097f14959ec7d19a388f11697cc50bf12542Johnny Chen                return false;
3221eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
322282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 11, 8);
322382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 3, 0);
322482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = BitIsSet(opcode, 20);
322582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
322682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            if (BadReg(Rd) || BadReg(Rm))
322782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen                return false;
322882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
322982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        case eEncodingA1:
323082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rd = Bits32(opcode, 15, 12);
323182f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            Rm = Bits32(opcode, 3, 0);
323282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            setflags = BitIsSet(opcode, 20);
323382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            imm5 = Bits32(opcode, 11, 7);
323482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            break;
323582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        default:
323682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            return false;
323782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        }
323882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
3239eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // A8.6.139 ROR (immediate)
3240eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        if (shift_type == SRType_ROR && imm5 == 0)
3241eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen            shift_type = SRType_RRX;
3242eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen
324382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // Get the first operand.
3244e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        uint32_t value = ReadCoreReg (Rm, &success);
324582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        if (!success)
324682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen            return false;
324782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
3248eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // Decode the shift amount if not RRX.
3249eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
325082f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
3251a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3252a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
3253a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
325482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
325582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
325682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        EmulateInstruction::Context context;
325782f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
325882f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        context.SetNoArgs ();
325982f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
326010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3261ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
326282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    }
326382f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen    return true;
326482f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen}
326582f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen
3266e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chenbool
32677bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3268e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen{
3269e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton    // assert(shift_type == SRType_ASR
3270e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton    //        || shift_type == SRType_LSL
3271e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton    //        || shift_type == SRType_LSR
3272e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton    //        || shift_type == SRType_ROR);
3273e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
3274e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    bool success = false;
3275e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
32767bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
3277e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    {
3278e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rd;    // the destination register
3279e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rn;    // the first operand register
3280e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3281e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t carry; // the carry bit after the shift operation
3282e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        bool setflags;
3283e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        switch (encoding) {
3284e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingT1:
3285e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 2, 0);
3286e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Rd;
3287e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 5, 3);
3288e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = !InITBlock();
3289e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
3290e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingT2:
3291e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 11, 8);
3292e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Bits32(opcode, 19, 16);
3293e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 3, 0);
3294e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = BitIsSet(opcode, 20);
3295e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3296e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen                return false;
3297e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
3298e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        case eEncodingA1:
3299e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rd = Bits32(opcode, 15, 12);
3300e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rn = Bits32(opcode, 3, 0);
3301e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            Rm = Bits32(opcode, 11, 8);
3302e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            setflags = BitIsSet(opcode, 20);
3303e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            if (Rd == 15 || Rn == 15 || Rm == 15)
3304e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen                return false;
3305e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            break;
3306e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        default:
3307e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
3308e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        }
3309e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
3310e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the first operand.
3311e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        uint32_t value = ReadCoreReg (Rn, &success);
3312e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        if (!success)
3313e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
3314e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the Rm register content.
3315e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        uint32_t val = ReadCoreReg (Rm, &success);
3316e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        if (!success)
3317e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
3318e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
3319e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // Get the shift amount.
3320e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        uint32_t amt = Bits32(val, 7, 0);
3321e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
3322a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3323a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
3324a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
3325e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
3326e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // The context specifies that an immediate is to be moved into Rd.
3327e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        EmulateInstruction::Context context;
3328e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
3329e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        context.SetNoArgs ();
3330e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
333110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3332e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen            return false;
3333e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    }
3334e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen    return true;
3335e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen}
3336e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen
3337b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// LDM loads multiple registers from consecutive memory locations, using an
3338713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// address from a base register.  Optionally the address just above the highest of those locations
3339b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice// can be written back to the base register.
3340b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Ticebool
33417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3342b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice{
3343b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#if 0
3344b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    // ARM pseudo code...
3345b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    if ConditionPassed()
3346b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3347b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        address = R[n];
3348b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3349b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        for i = 0 to 14
3350b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if registers<i> == '1' then
3351b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                R[i] = MemA[address, 4]; address = address + 4;
3352b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if registers<15> == '1' then
3353b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            LoadWritePC (MemA[address, 4]);
3354b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3355b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3356b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3357b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3358b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice#endif
3359b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3360b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    bool success = false;
3361107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    bool conditional = false;
3362107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (ConditionPassed(opcode, &conditional))
3363b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    {
3364b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        uint32_t n;
3365b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        uint32_t registers = 0;
3366b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        bool wback;
3367b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3368b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        switch (encoding)
3369b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
3370b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingT1:
3371bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3372b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 10, 8);
3373b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 7, 0);
3374b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3375b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsClear (registers, n);
3376b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                // if BitCount(registers) < 1 then UNPREDICTABLE;
3377b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (BitCount(registers) < 1)
3378b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3379b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
3380b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingT2:
3381bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if W == '1' && Rn == '1101' then SEE POP;
3382bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3383b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 19, 16);
3384b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 15, 0);
3385b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3386b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsSet (opcode, 21);
3387b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3388bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3389b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if ((n == 15)
3390b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitCount (registers) < 2)
3391b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3392b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3393b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3394bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3395098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3396b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3397b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3398bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if wback && registers<n> == '1' then UNPREDICTABLE;
3399b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (wback
3400b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    && BitIsSet (registers, n))
3401b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3402b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
3403b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
3404b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            case eEncodingA1:
3405b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                n = Bits32 (opcode, 19, 16);
3406b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                registers = Bits32 (opcode, 15, 0);
3407b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                wback = BitIsSet (opcode, 21);
3408b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if ((n == 15)
3409b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    || (BitCount (registers) < 1))
3410b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3411b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                break;
3412b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            default:
3413b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
3414b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
3415b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3416b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        int32_t offset = 0;
3417b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3418b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (!success)
3419b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            return false;
342085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
34219bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
34229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3423c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
3424c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
34259bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
3426b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3427b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        for (int i = 0; i < 14; ++i)
3428b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
3429b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (BitIsSet (registers, i))
3430b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            {
343185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                context.type = EmulateInstruction::eContextRegisterPlusOffset;
34329bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset);
3433b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (wback && (n == 13)) // Pop Instruction
3434107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton                {
3435107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton                    if (conditional)
3436107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton                        context.type = EmulateInstruction::eContextRegisterLoad;
3437107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton                    else
3438107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton                        context.type = EmulateInstruction::eContextPopRegisterOffStack;
3439107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton                }
3440b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3441b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                // R[i] = MemA [address, 4]; address = address + 4;
3442cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3443b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (!success)
3444b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3445b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3446b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3447b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                    return false;
3448b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3449b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                offset += addr_byte_size;
3450b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            }
3451b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
3452b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3453b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (BitIsSet (registers, 15))
3454b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
3455b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            //LoadWritePC (MemA [address, 4]);
345685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            context.type = EmulateInstruction::eContextRegisterPlusOffset;
34579bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3458cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3459b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (!success)
3460b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
3461e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3462668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
3463b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
3464b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
3465b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3466b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (wback && BitIsClear (registers, n))
3467b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        {
3468fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            // R[n] = R[n] + 4 * BitCount (registers)
3469fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            int32_t offset = addr_byte_size * BitCount (registers);
3470fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
34719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3472b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3473b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3474b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice                return false;
3475b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        }
3476b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        if (wback && BitIsSet (registers, n))
3477b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice            // R[n] bits(32) UNKNOWN;
3478713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
3479b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    }
3480b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice    return true;
3481b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice}
3482713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3483bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3484bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// The consecutive memory locations end at this address and the address just below the lowest of those locations
3485bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice// can optionally be written back to the base register.
3486713c2665a27096b68f3f8956222375354f1292f8Caroline Ticebool
34877bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3488713c2665a27096b68f3f8956222375354f1292f8Caroline Tice{
3489713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#if 0
3490713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    // ARM pseudo code...
3491713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    if ConditionPassed() then
3492713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        EncodingSpecificOperations();
3493713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        address = R[n] - 4*BitCount(registers) + 4;
3494713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3495713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        for i = 0 to 14
3496bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
3497713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  R[i] = MemA[address,4]; address = address + 4;
3498713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3499bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then
3500713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            LoadWritePC(MemA[address,4]);
3501713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3502bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3503bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3504713c2665a27096b68f3f8956222375354f1292f8Caroline Tice#endif
3505713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3506713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    bool success = false;
3507713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
35087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
3509713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    {
3510713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        uint32_t n;
3511713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        uint32_t registers = 0;
3512713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        bool wback;
3513713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
3514713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3515713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // EncodingSpecificOperations();
3516713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        switch (encoding)
3517713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
3518713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            case eEncodingA1:
3519bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3520713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                n = Bits32 (opcode, 19, 16);
3521713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                registers = Bits32 (opcode, 15, 0);
3522713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                wback = BitIsSet (opcode, 21);
3523b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice
3524713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3525713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
3526713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                    return false;
3527713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3528713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                break;
3529713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3530713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            default:
3531713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3532713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3533713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // address = R[n] - 4*BitCount(registers) + 4;
3534713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3535713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        int32_t offset = 0;
3536bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t Rn = ReadCoreReg (n, &success);
3537713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3538713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
3539713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
3540713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3541bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3542713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
35439bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
35449bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3545c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
3546c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
35479bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
3548713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3549713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // for i = 0 to 14
3550713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        for (int i = 0; i < 14; ++i)
3551713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
3552bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if registers<i> == '1' then
3553713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (BitIsSet (registers, i))
3554713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            {
3555713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  // R[i] = MemA[address,4]; address = address + 4;
3556bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3557cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3558713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  if (!success)
3559713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                      return false;
3560713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3561713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                      return false;
3562713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                  offset += addr_byte_size;
3563713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            }
3564713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3565713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3566bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then
3567713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        //     LoadWritePC(MemA[address,4]);
3568713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (BitIsSet (registers, 15))
3569713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
35709bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3571cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3572713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!success)
3573713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
357444c10f05a667cd279c6baea7b80b40b49c02f20cJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3575668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
3576713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3577713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3578713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3579bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3580713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (wback && BitIsClear (registers, n))
3581713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        {
3582713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!success)
3583713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3584fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3585fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
3586fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
35879bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3588bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            addr_t addr = Rn + offset;
3589713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3590713c2665a27096b68f3f8956222375354f1292f8Caroline Tice                return false;
3591713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        }
3592713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3593bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3594713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (wback && BitIsSet (registers, n))
3595713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
3596713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    }
3597713c2665a27096b68f3f8956222375354f1292f8Caroline Tice    return true;
3598713c2665a27096b68f3f8956222375354f1292f8Caroline Tice}
3599713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3600713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3601713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3602713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// be optionally written back to the base register.
36030b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Ticebool
36047bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
36050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice{
36060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#if 0
36070b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    // ARM pseudo code...
36080b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    if ConditionPassed() then
36090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
36100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        address = R[n] - 4*BitCount(registers);
36110b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36120b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        for i = 0 to 14
3613bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
36140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                  R[i] = MemA[address,4]; address = address + 4;
3615bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then
36160b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                  LoadWritePC(MemA[address,4]);
36170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3618bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3619bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
36200b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice#endif
36210b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36220b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    bool success = false;
36230b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
36250b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    {
36260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        uint32_t n;
36270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        uint32_t registers = 0;
36280b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        bool wback;
36290b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
36300b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        switch (encoding)
36310b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
36320b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            case eEncodingT1:
3633bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
36340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                n = Bits32 (opcode, 19, 16);
36350b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                registers = Bits32 (opcode, 15, 0);
3636b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
36370b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                wback = BitIsSet (opcode, 21);
36380b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3639bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
36400b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if ((n == 15)
36410b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    || (BitCount (registers) < 2)
36420b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
36430b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
36440b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3645bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3646098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
36470b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
36480b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3649bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if wback && registers<n> == '1' then UNPREDICTABLE;
36500b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (wback && BitIsSet (registers, n))
36510b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
36520b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36530b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                break;
36540b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36550b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            case eEncodingA1:
3656bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
36570b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                n = Bits32 (opcode, 19, 16);
36580b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                registers = Bits32 (opcode, 15, 0);
36590b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                wback = BitIsSet (opcode, 21);
36600b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36610b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
36620b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if ((n == 15) || (BitCount (registers) < 1))
36630b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
36640b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36650b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                break;
36660b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36670b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            default:
36680b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
36690b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
36700b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3671713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        // address = R[n] - 4*BitCount(registers);
3672713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
36730b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        int32_t offset = 0;
3674bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3675713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3676713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
3677713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
3678713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3679bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t address = Rn - (addr_byte_size * BitCount (registers));
36809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
36819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3682c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
3683c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3684bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
36850b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36860b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        for (int i = 0; i < 14; ++i)
36870b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
36880b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (BitIsSet (registers, i))
36890b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            {
36900b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                // R[i] = MemA[address,4]; address = address + 4;
3691bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3692cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
36930b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (!success)
36940b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
36950b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36960b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
36970b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                    return false;
36980b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
36990b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                offset += addr_byte_size;
37000b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            }
37010b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
37020b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3703bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then
37040b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        //     LoadWritePC(MemA[address,4]);
37050b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (BitIsSet (registers, 15))
37060b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
37079bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3708cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
37090b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!success)
37100b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
3711e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3712668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
37130b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
37140b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
37150b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3716bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
37170b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (wback && BitIsClear (registers, n))
37180b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        {
37190b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!success)
37200b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
3721fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3722fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
3723fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
37249bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3725bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            addr_t addr = Rn + offset;
37260b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
37270b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice                return false;
37280b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        }
37290b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3730bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
37310b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice        if (wback && BitIsSet (registers, n))
3732713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
37330b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    }
37340b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice    return true;
37350b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice}
373685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3737713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3738713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3739713c2665a27096b68f3f8956222375354f1292f8Caroline Tice// optinoally be written back to the base register.
374085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Ticebool
37417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
374285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice{
374385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#if 0
374485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    if ConditionPassed() then
374585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        EncodingSpecificOperations();
374685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        address = R[n] + 4;
374785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
374885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        for i = 0 to 14
3749bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
375085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                  R[i] = MemA[address,4]; address = address + 4;
3751bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then
375285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            LoadWritePC(MemA[address,4]);
375385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3754bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3755bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
375685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice#endif
375785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
375885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    bool success = false;
375985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
37607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
376185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    {
376285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        uint32_t n;
376385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        uint32_t registers = 0;
376485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        bool wback;
376585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
376685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        switch (encoding)
376785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
376885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            case eEncodingA1:
3769bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
377085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                n = Bits32 (opcode, 19, 16);
377185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                registers = Bits32 (opcode, 15, 0);
377285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                wback = BitIsSet (opcode, 21);
377385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
377485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
377585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if ((n == 15) || (BitCount (registers) < 1))
377685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
377785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
377885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                break;
377985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            default:
378085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
378185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
378285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        // address = R[n] + 4;
378385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
378485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        int32_t offset = 0;
3785bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3786713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3787713c2665a27096b68f3f8956222375354f1292f8Caroline Tice        if (!success)
3788713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return false;
3789713c2665a27096b68f3f8956222375354f1292f8Caroline Tice
3790bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t address = Rn + addr_byte_size;
379185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
37929bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
37939bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3794c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
3795c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
37969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.SetRegisterPlusOffset (dwarf_reg, offset);
379785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
379885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        for (int i = 0; i < 14; ++i)
379985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
380085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (BitIsSet (registers, i))
380185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            {
380285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                // R[i] = MemA[address,4]; address = address + 4;
380385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3804bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3805cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
380685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if (!success)
380785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
380885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
380985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
381085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                    return false;
381185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
381285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                offset += addr_byte_size;
381385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            }
381485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
381585aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3816bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then
381785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        //     LoadWritePC(MemA[address,4]);
381885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (BitIsSet (registers, 15))
381985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
38209bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (dwarf_reg, offset);
3821cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
382285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!success)
382385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
3824e62b50d64e9cdf806a36cefd4cbf96250679669dJohnny Chen            // In ARMv5T and above, this is an interworking branch.
3825668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen            if (!LoadWritePC(context, data))
382685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
382785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
382885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3829bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
383085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (wback && BitIsClear (registers, n))
383185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        {
383285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!success)
383385aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
3834fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
3835fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = addr_byte_size * BitCount (registers);
3836fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
38379bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
3838bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            addr_t addr = Rn + offset;
383985aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
384085aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice                return false;
384185aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        }
384285aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice
3843bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
384485aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice        if (wback && BitIsSet (registers, n))
3845713c2665a27096b68f3f8956222375354f1292f8Caroline Tice            return WriteBits32Unknown (n);
384685aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    }
384785aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice    return true;
384885aab33e2d866be406aa0ecc96cd37aa7a46a35cCaroline Tice}
38490b29e24ecd86048ac5d722dc964e55bab49f72aaCaroline Tice
3850ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// Load Register (immediate) calculates an address from a base register value and
3851ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// an immediate offset, loads a word from memory, and writes to a register.
3852ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// LDR (immediate, Thumb)
3853ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool
38547bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3855ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{
3856ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#if 0
3857ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    // ARM pseudo code...
3858ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    if (ConditionPassed())
3859ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    {
3860ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3861ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3862ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        address = if index then offset_addr else R[n];
3863ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        data = MemU[address,4];
3864ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if wback then R[n] = offset_addr;
3865ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if t == 15 then
3866ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3867ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        elsif UnalignedSupport() || address<1:0> = '00' then
3868ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            R[t] = data;
3869ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3870ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    }
3871ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen#endif
3872ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3873ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    bool success = false;
3874ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
38757bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
3876ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    {
3877ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t Rt; // the destination register
3878ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t Rn; // the base register
3879ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t imm32; // the immediate offset used to form the address
3880ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        addr_t offset_addr; // the offset address
3881ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        addr_t address; // the calculated address
3882ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        uint32_t data; // the literal data value from memory load
3883ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        bool add, index, wback;
3884ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        switch (encoding) {
3885baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            case eEncodingT1:
388655e569e255b7e1bd510d55820385db2a5ba1426eCaroline Tice                Rt = Bits32(opcode, 2, 0);
388755e569e255b7e1bd510d55820385db2a5ba1426eCaroline Tice                Rn = Bits32(opcode, 5, 3);
3888baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3889baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE
3890baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                add = true;
3891baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                index = true;
3892baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                wback = false;
3893baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3894baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                break;
3895baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3896baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            case eEncodingT2:
3897bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3898baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                Rt = Bits32 (opcode, 10, 8);
3899baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                Rn = 13;
3900baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
3901baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3902baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
3903baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                index = true;
3904baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                add = true;
3905baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                wback = false;
3906baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3907baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                break;
3908baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3909baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            case eEncodingT3:
3910bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDR (literal);
3911baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3912baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                Rt = Bits32 (opcode, 15, 12);
3913baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                Rn = Bits32 (opcode, 19, 16);
3914baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
3915baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3916baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
3917baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                index = true;
3918baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                add = true;
3919baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                wback = false;
3920baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3921baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3922baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3923baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                    return false;
3924baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3925baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                break;
3926baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3927baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            case eEncodingT4:
3928bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDR (literal);
3929bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3930bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3931bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '0' then UNDEFINED;
3932baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3933baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                    return false;
3934baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3935baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3936baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                Rt = Bits32 (opcode, 15, 12);
3937baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                Rn = Bits32 (opcode, 19, 16);
3938baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
3939baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3940bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3941baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                index = BitIsSet (opcode, 10);
3942baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                add = BitIsSet (opcode, 9);
3943baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                wback = BitIsSet (opcode, 8);
3944baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3945baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3946baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3947baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                    return false;
3948baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3949baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                break;
3950baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice
3951baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            default:
3952baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                return false;
3953ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3954baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice        uint32_t base = ReadCoreReg (Rn, &success);
3955ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (!success)
3956ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3957ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (add)
3958ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            offset_addr = base + imm32;
3959ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else
3960ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            offset_addr = base - imm32;
3961ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3962ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        address = (index ? offset_addr : base);
3963ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3964c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
3965c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3966ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (wback)
3967ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
39689bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            EmulateInstruction::Context ctx;
3969baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3970baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
39719bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
3972ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3973ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3974ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3975ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3976ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        // Prepare to write to the Rt register.
39779bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
3978baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice        context.type = EmulateInstruction::eContextRegisterLoad;
3979baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3980ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3981ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        // Read memory from the address.
3982cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        data = MemURead(context, address, 4, 0, &success);
3983ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (!success)
3984ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            return false;
3985ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
3986ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        if (Rt == 15)
3987ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
3988ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (Bits32(address, 1, 0) == 0)
3989ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            {
3990668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen                if (!LoadWritePC(context, data))
3991ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                    return false;
3992ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            }
3993ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            else
3994ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
3995ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
3996ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3997ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        {
3998ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3999ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen                return false;
4000ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        }
4001ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen        else
4002baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice            WriteBits32Unknown (Rt);
4003ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    }
4004ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    return true;
4005ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen}
4006ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
4007af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4008af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4009af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
4010fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Ticebool
40117bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4012fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice{
4013fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#if 0
4014fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    if ConditionPassed() then
4015fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4016fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        address = R[n];
4017fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4018fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        for i = 0 to 14
4019bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
4020fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
4021fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4022fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                else
4023fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    MemA[address,4] = R[i];
4024fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                address = address + 4;
4025fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4026bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then // Only possible for encoding A1
4027fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            MemA[address,4] = PCStoreValue();
4028fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if wback then R[n] = R[n] + 4*BitCount(registers);
4029fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice#endif
4030fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4031fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    bool success = false;
4032fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
40337bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
4034fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    {
4035fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        uint32_t n;
4036fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        uint32_t registers = 0;
4037fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        bool wback;
4038fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
4039fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4040fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4041fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        switch (encoding)
4042fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
4043fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingT1:
4044bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4045fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 10, 8);
4046fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 7, 0);
4047b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4048fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = true;
4049fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4050fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if BitCount(registers) < 1 then UNPREDICTABLE;
4051fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if (BitCount (registers) < 1)
4052fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
4053fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4054fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
4055fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4056fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingT2:
4057bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4058fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 19, 16);
4059fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 15, 0);
4060b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4061fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = BitIsSet (opcode, 21);
4062fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4063fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4064fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if ((n == 15) || (BitCount (registers) < 2))
4065fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
4066fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4067bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if wback && registers<n> == '1' then UNPREDICTABLE;
4068fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if (wback && BitIsSet (registers, n))
4069fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
4070fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4071fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
4072fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4073fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            case eEncodingA1:
4074bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4075fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                n = Bits32 (opcode, 19, 16);
4076fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                registers = Bits32 (opcode, 15, 0);
4077fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                wback = BitIsSet (opcode, 21);
4078fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4079fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4080fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
4081fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                    return false;
4082fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4083fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                break;
4084fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4085fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            default:
4086fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
4087fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
4088fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4089fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // address = R[n];
4090fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        int32_t offset = 0;
4091fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4092fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (!success)
4093fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            return false;
4094fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
40959bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        EmulateInstruction::Context context;
40969bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
4097c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
4098c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4099fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4100fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // for i = 0 to 14
41017e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        uint32_t lowest_set_bit = 14;
41027e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t i = 0; i < 14; ++i)
4103fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
4104bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if registers<i> == '1' then
4105fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (BitIsSet (registers, i))
4106fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            {
4107fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  if (i < lowest_set_bit)
4108fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      lowest_set_bit = i;
4109fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  // if i == n && wback && i != LowestSetBit(registers) then
4110fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  if ((i == n) && wback && (i != lowest_set_bit))
4111fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4112fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      WriteBits32UnknownToMemory (address + offset);
4113fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  else
4114fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  {
4115fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                     // MemA[address,4] = R[i];
4116fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4117fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                      if (!success)
4118fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                          return false;
4119fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4120c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                      RegisterInfo data_reg;
4121c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                      GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
41229bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4123cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
4124fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                          return false;
4125fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  }
4126fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4127fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  // address = address + 4;
4128fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                  offset += addr_byte_size;
4129fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            }
4130fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
4131fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4132bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then // Only possible for encoding A1
4133fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //     MemA[address,4] = PCStoreValue();
4134fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (BitIsSet (registers, 15))
4135fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
4136c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo pc_reg;
4137c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
41389bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
41398d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4140fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (!success)
4141fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
4142fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
41438d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4144fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
4145fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
4146fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4147fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // if wback then R[n] = R[n] + 4*BitCount(registers);
4148fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        if (wback)
4149fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        {
4150fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            offset = addr_byte_size * BitCount (registers);
4151fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
41529bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            context.SetImmediateSigned (offset);
4153fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            addr_t data = address + offset;
4154fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4155fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice                return false;
4156fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        }
4157fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    }
4158fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice    return true;
4159fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice}
4160fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
4161af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4162af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4163af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
41641511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Ticebool
41657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
41661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice{
41671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#if 0
41681511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    if ConditionPassed() then
41691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        EncodingSpecificOperations();
41701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        address = R[n] - 4*BitCount(registers) + 4;
41711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
41721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        for i = 0 to 14
4173bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
41741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
41751511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN;
41761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                else
41771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    MemA[address,4] = R[i];
41781511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                address = address + 4;
41791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
4180bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then
41811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            MemA[address,4] = PCStoreValue();
41821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
41831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if wback then R[n] = R[n] - 4*BitCount(registers);
41841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice#endif
41851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
41861511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    bool success = false;
41871511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
41887bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
41891511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    {
41901511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        uint32_t n;
41911511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        uint32_t registers = 0;
41921511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        bool wback;
41931511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
41941511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
41951511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // EncodingSpecificOperations();
41961511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        switch (encoding)
41971511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
41981511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            case eEncodingA1:
4199bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
42001511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                n = Bits32 (opcode, 19, 16);
42011511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                registers = Bits32 (opcode, 15, 0);
42021511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                wback = BitIsSet (opcode, 21);
42031511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42041511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
42051511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if ((n == 15) || (BitCount (registers) < 1))
42061511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    return false;
42071511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                break;
42081511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            default:
42091511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
42101511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
42111511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42121511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // address = R[n] - 4*BitCount(registers) + 4;
42131511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        int32_t offset = 0;
4214bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t Rn = ReadCoreReg (n, &success);
42151511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (!success)
42161511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            return false;
42171511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
4218bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
42191511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42201511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        EmulateInstruction::Context context;
42211511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
4222c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
4223c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
42241511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42251511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // for i = 0 to 14
42267e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        uint32_t lowest_bit_set = 14;
42277e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t i = 0; i < 14; ++i)
42281511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
4229bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if registers<i> == '1' then
42301511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (BitIsSet (registers, i))
42311511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            {
42321511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if (i < lowest_bit_set)
42331511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    lowest_bit_set = i;
42341511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                //if i == n && wback && i != LowestSetBit(registers) then
42351511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                if ((i == n) && wback && (i != lowest_bit_set))
42361511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    // MemA[address,4] = bits(32) UNKNOWN;
42371511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    WriteBits32UnknownToMemory (address + offset);
42381511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                else
42391511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                {
42401511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    // MemA[address,4] = R[i];
42411511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
42421511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                    if (!success)
42431511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                        return false;
42441511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
4245c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                    RegisterInfo data_reg;
4246c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4247bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4248cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
42491511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                        return false;
42501511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                }
42511511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42521511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                // address = address + 4;
42531511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                offset += addr_byte_size;
42541511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            }
42551511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
42561511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
4257bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then
42581511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        //    MemA[address,4] = PCStoreValue();
42591511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (BitIsSet (registers, 15))
42601511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
4261c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo pc_reg;
4262c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
42631511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
42648d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            const uint32_t pc = ReadCoreReg (PC_REG, &success);
42651511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (!success)
42661511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
42671511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42688d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
42691511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
42701511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
42711511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
42721511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        // if wback then R[n] = R[n] - 4*BitCount(registers);
42731511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        if (wback)
42741511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        {
4275af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
42761511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
42771511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            context.SetImmediateSigned (offset);
4278bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            addr_t data = Rn + offset;
42791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
42801511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice                return false;
42811511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice        }
42821511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    }
42831511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice    return true;
42841511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice}
42851511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
4286af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4287af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4288af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// those locations can optionally be written back to the base register.
4289b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Ticebool
42907bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4291b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice{
4292b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#if 0
4293b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    if ConditionPassed() then
4294b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4295b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        address = R[n] - 4*BitCount(registers);
4296b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4297b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        for i = 0 to 14
4298bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
4299b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if i == n && wback && i != LowestSetBit(registers) then
4300b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4301b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                else
4302b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    MemA[address,4] = R[i];
4303b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                address = address + 4;
4304b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4305bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then // Only possible for encoding A1
4306b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            MemA[address,4] = PCStoreValue();
4307b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4308b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if wback then R[n] = R[n] - 4*BitCount(registers);
4309b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice#endif
4310b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4311b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4312b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    bool success = false;
4313b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
43147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
4315b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    {
4316b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        uint32_t n;
4317b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        uint32_t registers = 0;
4318b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        bool wback;
4319b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
4320b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4321b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4322b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        switch (encoding)
4323b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
4324b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            case eEncodingT1:
4325bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if W == '1' && Rn == '1101' then SEE PUSH;
4326b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4327b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
4328b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // See PUSH
4329b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
4330bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4331b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                n = Bits32 (opcode, 19, 16);
4332b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = Bits32 (opcode, 15, 0);
4333b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4334b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                wback = BitIsSet (opcode, 21);
4335b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4336b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((n == 15) || BitCount (registers) < 2)
4337b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
4338bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if wback && registers<n> == '1' then UNPREDICTABLE;
4339b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (wback && BitIsSet (registers, n))
4340b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
4341b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                break;
4342b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4343b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            case eEncodingA1:
4344061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4345b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4346b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
4347b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // See Push
4348b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
4349bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4350b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                n = Bits32 (opcode, 19, 16);
4351b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                registers = Bits32 (opcode, 15, 0);
4352b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                wback = BitIsSet (opcode, 21);
4353b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4354b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((n == 15) || BitCount (registers) < 1)
4355b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    return false;
4356b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                break;
4357b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4358b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            default:
4359b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
4360b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
4361b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4362b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // address = R[n] - 4*BitCount(registers);
4363b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4364b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        int32_t offset = 0;
4365bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4366b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (!success)
4367b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        return false;
4368b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4369bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4370b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4371b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        EmulateInstruction::Context context;
4372b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
4373c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
4374c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4375b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4376b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // for i = 0 to 14
4377bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        uint32_t lowest_set_bit = 14;
43787e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t i = 0; i < 14; ++i)
4379b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
4380bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if registers<i> == '1' then
4381b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (BitIsSet (registers, i))
4382b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            {
4383b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if (i < lowest_set_bit)
4384b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    lowest_set_bit = i;
4385b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // if i == n && wback && i != LowestSetBit(registers) then
4386b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                if ((i == n) && wback && (i != lowest_set_bit))
4387b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4388b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    WriteBits32UnknownToMemory (address + offset);
4389b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                else
4390b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                {
4391b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    // MemA[address,4] = R[i];
4392b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4393b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                    if (!success)
4394b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                        return false;
4395b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4396c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                    RegisterInfo data_reg;
4397c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4398bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4399cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4400b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                        return false;
4401b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                }
4402b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4403b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                // address = address + 4;
4404b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                offset += addr_byte_size;
4405b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            }
4406b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
4407b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4408bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then // Only possible for encoding A1
4409b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        //     MemA[address,4] = PCStoreValue();
4410b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (BitIsSet (registers, 15))
4411b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
4412c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo pc_reg;
4413c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4414b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
44158d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4416b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (!success)
4417b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
4418b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
44198d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4420b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
4421b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
4422b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
4423b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        // if wback then R[n] = R[n] - 4*BitCount(registers);
4424b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        if (wback)
4425b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        {
4426af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            offset = (addr_byte_size * BitCount (registers)) * -1;
4427af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4428af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.SetImmediateSigned (offset);
4429bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            addr_t data = Rn + offset;
4430af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4431af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
4432af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
4433af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    }
4434af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    return true;
4435af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice}
4436af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4437af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4438af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4439af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice// of those locations can optionally be written back to the base register.
4440af556564f80fd417a9158754f5e2ee692e183f6dCaroline Ticebool
44417bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4442af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice{
4443af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#if 0
4444af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    if ConditionPassed() then
4445af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        EncodingSpecificOperations();
4446af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        address = R[n] + 4;
4447af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4448af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        for i = 0 to 14
4449bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if registers<i> == '1' then
4450af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if i == n && wback && i != LowestSetBit(registers) then
4451af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    MemA[address,4] = bits(32) UNKNOWN;
4452af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                else
4453af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    MemA[address,4] = R[i];
4454af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                address = address + 4;
4455af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4456bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if registers<15> == '1' then
4457af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            MemA[address,4] = PCStoreValue();
4458af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4459af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if wback then R[n] = R[n] + 4*BitCount(registers);
4460af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice#endif
4461af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4462af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    bool success = false;
4463af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
44647bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
4465af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice    {
4466af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t n;
4467af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t registers = 0;
4468af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        bool wback;
4469af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
4470af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4471af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // EncodingSpecificOperations();
4472af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        switch (encoding)
4473af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
4474af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            case eEncodingA1:
4475bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4476af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                n = Bits32 (opcode, 19, 16);
4477af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                registers = Bits32 (opcode, 15, 0);
4478af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                wback = BitIsSet (opcode, 21);
4479af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4480af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4481af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if ((n == 15) && (BitCount (registers) < 1))
4482af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    return false;
4483af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                break;
4484af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            default:
4485af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
4486af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
4487af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // address = R[n] + 4;
4488af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4489af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        int32_t offset = 0;
4490bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t Rn = ReadCoreReg (n, &success);
4491af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (!success)
4492af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            return false;
4493af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4494bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        addr_t address = Rn + addr_byte_size;
4495af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4496af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        EmulateInstruction::Context context;
4497af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        context.type = EmulateInstruction::eContextRegisterStore;
4498c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
4499c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4500af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4501af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        uint32_t lowest_set_bit = 14;
4502af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // for i = 0 to 14
45037e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t i = 0; i < 14; ++i)
4504af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
4505bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if registers<i> == '1' then
4506af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (BitIsSet (registers, i))
4507af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            {
4508af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if (i < lowest_set_bit)
4509af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    lowest_set_bit = i;
4510af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // if i == n && wback && i != LowestSetBit(registers) then
4511af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                if ((i == n) && wback && (i != lowest_set_bit))
4512af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    // MemA[address,4] = bits(32) UNKNOWN;
4513af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    WriteBits32UnknownToMemory (address + offset);
4514af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // else
4515af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                else
4516af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                {
4517af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    // MemA[address,4] = R[i];
4518af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4519af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                    if (!success)
4520af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                        return false;
4521af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4522c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                    RegisterInfo data_reg;
4523c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4524bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4525cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4526af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                        return false;
4527af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                }
4528af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4529af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                // address = address + 4;
4530af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                offset += addr_byte_size;
4531af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            }
4532af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
4533af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4534bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if registers<15> == '1' then
4535af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            // MemA[address,4] = PCStoreValue();
4536af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (BitIsSet (registers, 15))
4537af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
4538c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo pc_reg;
4539c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4540af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            context.SetRegisterPlusOffset (pc_reg, 8);
45418d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4542af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            if (!success)
4543af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice            return false;
4544af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
45458d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4546af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice                return false;
4547af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        }
4548af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
4549af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        // if wback then R[n] = R[n] + 4*BitCount(registers);
4550af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        if (wback)
4551af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice        {
4552b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            offset = addr_byte_size * BitCount (registers);
4553b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4554b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            context.SetImmediateSigned (offset);
4555bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            addr_t data = Rn + offset;
4556b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4557b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice                return false;
4558b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice        }
4559b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    }
4560b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice    return true;
4561b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice}
45627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
45637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
45647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
45657fac857ec72051dc0a91b027719c275ea672a470Caroline Ticebool
45667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
45677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice{
45687fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#if 0
45697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    if ConditionPassed() then
45707fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
45717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
45727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        address = if index then offset_addr else R[n];
4573bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<1:0> == '00' then
45747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            MemU[address,4] = R[t];
45757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else // Can only occur before ARMv7
45767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            MemU[address,4] = bits(32) UNKNOWN;
45777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if wback then R[n] = offset_addr;
45787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice#endif
45797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
45807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    bool success = false;
45817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
45827bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
45837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    {
45847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
45857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
45867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t t;
45877fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t n;
45887fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        uint32_t imm32;
45897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool index;
45907fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool add;
45917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        bool wback;
45927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
45937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        switch (encoding)
45947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
45957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT1:
4596bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
45977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 2, 0);
45987fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 5, 3);
45997fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 10, 6) << 2;
46007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
46027fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
46037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = false;
46047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
46057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
46067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT2:
4608bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
46097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 10, 8);
46107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = 13;
46117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
46127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
46147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
46157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = true;
46167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
46177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
46187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT3:
4620bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then UNDEFINED;
46217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
46227fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
46237fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46247fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
46257fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 15, 12);
46267fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 19, 16);
46277fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
46287fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46297fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
46307fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = true;
46317fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = true;
46327fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = false;
46337fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46347fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if t == 15 then UNPREDICTABLE;
46357fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if (t == 15)
46367fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
46377fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
46387fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46397fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            case eEncodingT4:
4640bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4641bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4642bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
46437fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if ((Bits32 (opcode, 19, 16) == 15)
46447fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
46457fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
46467fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46477fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
46487fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                t = Bits32 (opcode, 15, 12);
46497fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                n = Bits32 (opcode, 19, 16);
46507fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
46517fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
4652bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
46537fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                index = BitIsSet (opcode, 10);
46547fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                add = BitIsSet (opcode, 9);
46557fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                wback = BitIsSet (opcode, 8);
46567fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46577fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
46587fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                if ((t == 15) || (wback && (n == t)))
46597fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                    return false;
46607fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                break;
46617fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46627fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            default:
46637fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
46647fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
46657fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46667fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        addr_t offset_addr;
46677fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        addr_t address;
4668b6f8d7ec6f0a91a805d4ffa0f6fe8dcd1ae5c4d3Caroline Tice
46697fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4670baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice        uint32_t base_address = ReadCoreReg (n, &success);
46717fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (!success)
46727fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            return false;
46737fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46747fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (add)
46757fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            offset_addr = base_address + imm32;
46767fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
46777fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            offset_addr = base_address - imm32;
46787fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46797fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // address = if index then offset_addr else R[n];
46807fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (index)
46817fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            address = offset_addr;
46827fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
46837fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            address = base_address;
46847fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
46857fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        EmulateInstruction::Context context;
46867fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        context.type = eContextRegisterStore;
4687c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
4688c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
46897fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
4690bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<1:0> == '00' then
46917fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
46927fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
46937fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            // MemU[address,4] = R[t];
46947fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
46957fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            if (!success)
46967fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
46977fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
4698c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo data_reg;
4699c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
47007fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            int32_t offset = address - base_address;
47017fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4702cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, address, data, addr_byte_size))
47037fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
47047fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
47057fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        else
47067fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
47077fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            // MemU[address,4] = bits(32) UNKNOWN;
47087fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            WriteBits32UnknownToMemory (address);
47097fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
47107fac857ec72051dc0a91b027719c275ea672a470Caroline Tice
47117fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        // if wback then R[n] = offset_addr;
47127fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        if (wback)
47137fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        {
47147fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.type = eContextRegisterLoad;
47157fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            context.SetAddress (offset_addr);
47167fac857ec72051dc0a91b027719c275ea672a470Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
47177fac857ec72051dc0a91b027719c275ea672a470Caroline Tice                return false;
47187fac857ec72051dc0a91b027719c275ea672a470Caroline Tice        }
47197fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    }
47207fac857ec72051dc0a91b027719c275ea672a470Caroline Tice    return true;
47217fac857ec72051dc0a91b027719c275ea672a470Caroline Tice}
4722af556564f80fd417a9158754f5e2ee692e183f6dCaroline Tice
47233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
47243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice// word from a register to memory.   The offset register value can optionally be shifted.
47253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Ticebool
47267bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
47273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice{
47283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#if 0
47293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    if ConditionPassed() then
47303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
47313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
47323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
47333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        address = if index then offset_addr else R[n];
47343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if t == 15 then // Only possible for encoding A1
47353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = PCStoreValue();
47363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
47373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = R[t];
4738bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
47393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            MemU[address,4] = data;
47403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else // Can only occur before ARMv7
47413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            MemU[address,4] = bits(32) UNKNOWN;
47423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if wback then R[n] = offset_addr;
47433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice#endif
47443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    bool success = false;
47463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47477bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
47483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    {
47493fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
47503fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47513fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t t;
47523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t n;
47533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t m;
47543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        ARM_ShifterType shift_t;
47553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t shift_n;
47563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool index;
47573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool add;
47583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        bool wback;
47593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
47613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        switch (encoding)
47623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
47633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingT1:
47643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
47653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
47663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 2, 0);
47673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 5, 3);
47683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 8, 6);
47693fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
47713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = true;
47723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = true;
47733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = false;
47743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
47763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_t = SRType_LSL;
47773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = 0;
47783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
47793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47803fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingT2:
4781bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then UNDEFINED;
47823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (Bits32 (opcode, 19, 16) == 15)
47833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
47843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
47863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 15, 12);
47873fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 19, 16);
47883fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 3, 0);
47893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47903fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
47913fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = true;
47923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = true;
47933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = false;
47943fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
47963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_t = SRType_LSL;
47973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
47983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
47993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if t == 15 || BadReg(m) then UNPREDICTABLE;
48003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if ((t == 15) || (BadReg (m)))
48013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
48023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
48033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            case eEncodingA1:
48053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            {
4806bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE STRT;
48073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
48083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                t = Bits32 (opcode, 15, 12);
48093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                n = Bits32 (opcode, 19, 16);
48103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                m = Bits32 (opcode, 3, 0);
48113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
4812bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
48133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                index = BitIsSet (opcode, 24);
48143fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                add = BitIsSet (opcode, 23);
48153fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
48163fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48173fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
48183fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                uint32_t typ = Bits32 (opcode, 6, 5);
48193fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
48203fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                shift_n = DecodeImmShift(typ, imm5, shift_t);
48213fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48223fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if m == 15 then UNPREDICTABLE;
48233fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (m == 15)
48243fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
48253fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48263fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
48273fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                if (wback && ((n == 15) || (n == t)))
48283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                    return false;
48293fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48303fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                break;
48313fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            }
48323fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            default:
48333fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
48343fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
48353fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48363fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t offset_addr;
48373fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t address;
48383fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        int32_t offset = 0;
48393fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48403fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
48413fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
48423fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
48433fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48443fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
48453fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
48463fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
48473fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48483fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4849a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4850a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
4851a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
48523fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48533fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
48543fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (add)
48553fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            offset_addr = base_address + offset;
48563fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
48573fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            offset_addr = base_address - offset;
48583fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48593fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // address = if index then offset_addr else R[n];
48603fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (index)
48613fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            address = offset_addr;
48623fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
48633fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            address = base_address;
48643fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48653fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        uint32_t data;
48663fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if t == 15 then // Only possible for encoding A1
48673fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (t == 15)
48683fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // data = PCStoreValue();
48698d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            data = ReadCoreReg (PC_REG, &success);
48703fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
48713fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // data = R[t];
48723fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
48733fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48743fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (!success)
48753fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            return false;
48763fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48773fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        EmulateInstruction::Context context;
48783fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        context.type = eContextRegisterStore;
48793fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
4880bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
48813fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (UnalignedSupport ()
48823fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            || (BitIsClear (address, 1) && BitIsClear (address, 0))
48833fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            || CurrentInstrSet() == eModeARM)
48843fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
48853fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // MemU[address,4] = data;
48863fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
4887c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo base_reg;
4888c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
48893fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
4890c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo data_reg;
4891c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
48923fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48933fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4894cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice            if (!MemUWrite (context, address, data, addr_byte_size))
48953fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
48963fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
48973fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
48983fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        else
48993fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            // MemU[address,4] = bits(32) UNKNOWN;
49003fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            WriteBits32UnknownToMemory (address);
49013fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
49023fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        // if wback then R[n] = offset_addr;
49033fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        if (wback)
49043fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        {
49053fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.type = eContextRegisterLoad;
49063fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            context.SetAddress (offset_addr);
49073fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
49083fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice                return false;
49093fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice        }
49103fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
49113fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    }
49123fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice    return true;
49133fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice}
491473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
491573a29de4b8f59594fd7a559c05fa795afe754551Caroline Ticebool
49167bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
491773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice{
491873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#if 0
491973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    if ConditionPassed() then
492073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
492173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
492273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        address = if index then offset_addr else R[n];
492373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        MemU[address,1] = R[t]<7:0>;
492473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if wback then R[n] = offset_addr;
492573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice#endif
492673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
492773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
492873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    bool success = false;
492973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
49307bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
493173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    {
493273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t t;
493373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t n;
493473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t imm32;
493573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool index;
493673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool add;
493773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        bool wback;
493873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
493973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        switch (encoding)
494073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        {
494173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT1:
494273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
494373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 2, 0);
494473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 5, 3);
494573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 10, 6);
494673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
494773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
494873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = true;
494973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = true;
495073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = false;
495173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
495273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
495373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT2:
4954bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then UNDEFINED;
495573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
495673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
495773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
495873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
495973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 15, 12);
496073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 19, 16);
496173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
496273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
496373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
496473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = true;
496573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = true;
496673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = false;
496773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
496873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if BadReg(t) then UNPREDICTABLE;
496973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (BadReg (t))
497073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
497173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
497273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
497373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            case eEncodingT3:
4974bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4975bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
497673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if (Bits32 (opcode, 19, 16) == 15)
497773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
497873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
497973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
498073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                t = Bits32 (opcode, 15, 12);
498173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                n = Bits32 (opcode, 19, 16);
498273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
498373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
4984bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
498573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                index = BitIsSet (opcode, 10);
498673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                add = BitIsSet (opcode, 9);
498773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                wback = BitIsSet (opcode, 8);
498873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
498973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
499073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                if ((BadReg (t)) || (wback && (n == t)))
499173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                    return false;
499273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                break;
499373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
499473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            default:
499573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                return false;
499673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        }
499773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
499873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t offset_addr;
499973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t address;
500073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
500173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (!success)
500273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
500373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
500473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
500573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (add)
500673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            offset_addr = base_address + imm32;
500773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        else
500873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            offset_addr = base_address - imm32;
500973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
501073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // address = if index then offset_addr else R[n];
501173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (index)
501273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            address = offset_addr;
501373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        else
501473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            address = base_address;
501573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
5016cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        // MemU[address,1] = R[t]<7:0>
5017c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
5018c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
501973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
5020c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
5021c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
502273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
502373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        EmulateInstruction::Context context;
502473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        context.type = eContextRegisterStore;
502573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
502673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
502773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
502873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (!success)
502973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
503073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
503173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        data = Bits32 (data, 7, 0);
503273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
5033cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice        if (!MemUWrite (context, address, data, 1))
503473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            return false;
503573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
503673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        // if wback then R[n] = offset_addr;
503773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        if (wback)
503873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        {
503973a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            context.type = eContextRegisterLoad;
504073a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            context.SetAddress (offset_addr);
504173a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
504273a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice                return false;
504373a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice        }
504473a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
504573a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    }
504673a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice
504773a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice    return true;
504873a29de4b8f59594fd7a559c05fa795afe754551Caroline Tice}
50498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
50508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// STRH (register) calculates an address from a base register value and an offset register value, and stores a
50518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
50528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Ticebool
50537bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
50548ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice{
50558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#if 0
50568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice    if ConditionPassed() then
50578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
50588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
50598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
50608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        address = if index then offset_addr else R[n];
5061bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> == '0' then
50628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            MemU[address,2] = R[t]<15:0>;
50638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        else // Can only occur before ARMv7
50648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            MemU[address,2] = bits(16) UNKNOWN;
50658ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if wback then R[n] = offset_addr;
50668ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice#endif
50678ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
50688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice    bool success = false;
50698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
50707bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
50718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice    {
50728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        uint32_t t;
50738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        uint32_t n;
50748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        uint32_t m;
50758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        bool index;
50768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        bool add;
50778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        bool wback;
50788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        ARM_ShifterType shift_t;
50798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        uint32_t shift_n;
50808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
50818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
50828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        switch (encoding)
50838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        {
50848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            case eEncodingT1:
50858ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
50868ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
50878ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                t = Bits32 (opcode, 2, 0);
50888ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                n = Bits32 (opcode, 5, 3);
50898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                m = Bits32 (opcode, 8, 6);
50908ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
50918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
50928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                index = true;
50938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                add = true;
50948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                wback = false;
50958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
50968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
50978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                shift_t = SRType_LSL;
50988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                shift_n = 0;
50998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51008ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                break;
51018ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51028ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            case eEncodingT2:
5103bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then UNDEFINED;
51048ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
51058ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                t = Bits32 (opcode, 15, 12);
51068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                n = Bits32 (opcode, 19, 16);
51078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                m = Bits32 (opcode, 3, 0);
51088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                if (n == 15)
51098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                    return false;
51108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
51128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                index = true;
51138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                add = true;
51148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                wback = false;
51158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
51178ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                shift_t = SRType_LSL;
51188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                shift_n = Bits32 (opcode, 5, 4);
51198ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51208ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
51218ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                if (BadReg (t) || BadReg (m))
51228ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                    return false;
51238ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51248ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                break;
51258ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51268ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            case eEncodingA1:
5127bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE STRHT;
51288ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
51298ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                t = Bits32 (opcode, 15, 12);
51308ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                n = Bits32 (opcode, 19, 16);
51318ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                m = Bits32 (opcode, 3, 0);
51328ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
5133bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
51348ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                index = BitIsSet (opcode, 24);
51358ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                add = BitIsSet (opcode, 23);
51368ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
51378ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51388ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
51398ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                shift_t = SRType_LSL;
51408ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                shift_n = 0;
51418ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51428ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // if t == 15 || m == 15 then UNPREDICTABLE;
51438ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                if ((t == 15) || (m == 15))
51448ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                    return false;
51458ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51468ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
51478ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                if (wback && ((n == 15) || (n == t)))
51488ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                    return false;
51498ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51508ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                break;
51518ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51528ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            default:
51538ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                return false;
51548ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        }
51558ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51568ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        uint32_t Rm = ReadCoreReg (m, &success);
51578ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if (!success)
51588ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            return false;
51598ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51608ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
51618ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if (!success)
51628ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            return false;
51638ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51648ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5165a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5166a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
5167a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
51688ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51698ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
51708ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        addr_t offset_addr;
51718ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if (add)
51728ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            offset_addr = Rn + offset;
51738ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        else
51748ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            offset_addr = Rn - offset;
51758ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51768ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        // address = if index then offset_addr else R[n];
51778ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        addr_t address;
51788ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if (index)
51798ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            address = offset_addr;
51808ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        else
51818ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            address = Rn;
51828ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51838ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        EmulateInstruction::Context context;
51848ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        context.type = eContextRegisterStore;
5185c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
5186c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5187c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo offset_reg;
5188c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
51898ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
5190bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> == '0' then
51918ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if (UnalignedSupport() || BitIsClear (address, 0))
51928ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        {
51938ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            // MemU[address,2] = R[t]<15:0>;
51948ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            uint32_t Rt = ReadCoreReg (t, &success);
51958ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            if (!success)
51968ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                return false;
51978ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
51988ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            EmulateInstruction::Context context;
51998ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            context.type = eContextRegisterStore;
5200c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo base_reg;
5201c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5202c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo offset_reg;
5203c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5204c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo data_reg;
5205c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
52068ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
52078ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
52088ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
52098ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                return false;
52108ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        }
52118ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        else // Can only occur before ARMv7
52128ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        {
52138ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            // MemU[address,2] = bits(16) UNKNOWN;
52148ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        }
52158ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
52168ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        // if wback then R[n] = offset_addr;
52178ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        if (wback)
52188ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        {
52198ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            context.type = eContextAdjustBaseRegister;
52208ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            context.SetAddress (offset_addr);
52218ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
52228ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice                return false;
52238ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice        }
52248ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice    }
52258ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice
52268ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice    return true;
52278ce836dbf416c4dfdbede109be5cc09b95918fd0Caroline Tice}
52283fd63e92ed8fda0007ad645ee3bf6b040f41e71eCaroline Tice
5229157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5230157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// and writes the result to the destination register.  It can optionally update the condition flags
5231157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// based on the result.
5232157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool
52337bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5234157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{
5235157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0
5236157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    // ARM pseudo code...
5237157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if ConditionPassed() then
5238157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EncodingSpecificOperations();
5239157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5240157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
5241157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
5242157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        else
5243157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            R[d] = result;
5244157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if setflags then
5245157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.N = result<31>;
5246157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.Z = IsZeroBit(result);
5247157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.C = carry;
5248157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.V = overflow;
5249157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif
5250157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5251157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    bool success = false;
5252157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
52537bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5254157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    {
5255157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t Rd, Rn;
5256157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5257157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        bool setflags;
5258157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        switch (encoding)
5259157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        {
5260157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingT1:
5261157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 11, 8);
5262157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
5263157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
5264157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5265157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (BadReg(Rd) || BadReg(Rn))
5266157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                return false;
5267157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
5268157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingA1:
5269157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 15, 12);
5270157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
5271157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
5272157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
52731f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
5274157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (Rd == 15 && setflags)
52751f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
5276157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
5277157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        default:
5278157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5279157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        }
5280157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5281157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // Read the first operand.
5282157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        int32_t val1 = ReadCoreReg(Rn, &success);
5283157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!success)
5284157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5285157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5286157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5287157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5288157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EmulateInstruction::Context context;
5289157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
5290157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.SetNoArgs ();
5291157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5292157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5293157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5294157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    }
5295157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    return true;
5296157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen}
5297157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5298157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5299157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// register value, and writes the result to the destination register.  It can optionally update the
5300157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen// condition flags based on the result.
5301157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenbool
53027bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5303157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{
5304157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#if 0
5305157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    // ARM pseudo code...
5306157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    if ConditionPassed() then
5307157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EncodingSpecificOperations();
5308157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5309157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5310157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
5311157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
5312157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        else
5313157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            R[d] = result;
5314157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if setflags then
5315157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.N = result<31>;
5316157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.Z = IsZeroBit(result);
5317157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.C = carry;
5318157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                APSR.V = overflow;
5319157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen#endif
5320157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5321157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    bool success = false;
5322157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
53237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5324157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    {
5325157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t Rd, Rn, Rm;
5326157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        ARM_ShifterType shift_t;
5327157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
5328157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        bool setflags;
5329157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        switch (encoding)
5330157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        {
5331157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingT1:
5332157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
5333157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rm = Bits32(opcode, 5, 3);
5334157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = !InITBlock();
5335157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_t = SRType_LSL;
5336157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            shift_n = 0;
5337ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
5338157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingT2:
5339157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 11, 8);
5340157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
5341157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rm = Bits32(opcode, 3, 0);
5342157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
53433dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5344157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5345157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen                return false;
5346157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
5347157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        case eEncodingA1:
5348157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rd = Bits32(opcode, 15, 12);
5349157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rn = Bits32(opcode, 19, 16);
5350157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            Rm = Bits32(opcode, 3, 0);
5351157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            setflags = BitIsSet(opcode, 20);
53523dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
53531f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
5354157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            if (Rd == 15 && setflags)
53551f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
5356157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            break;
5357157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        default:
5358157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5359157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        }
5360157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5361157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // Read the first operand.
5362157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        int32_t val1 = ReadCoreReg(Rn, &success);
5363157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!success)
5364157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5365157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5366157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // Read the second operand.
5367157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        int32_t val2 = ReadCoreReg(Rm, &success);
5368157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!success)
5369157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5370157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5371a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5372a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
5373a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
5374157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5375157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5376157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        EmulateInstruction::Context context;
5377157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
5378157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        context.SetNoArgs ();
5379157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5380157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5381157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            return false;
5382157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    }
5383157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    return true;
5384157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen}
5385157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
5386a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// This instruction adds an immediate value to the PC value to form a PC-relative address,
5387a695f958db37c102d480a9c0780abec262ba8332Johnny Chen// and writes the result to the destination register.
5388a695f958db37c102d480a9c0780abec262ba8332Johnny Chenbool
53897bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5390a695f958db37c102d480a9c0780abec262ba8332Johnny Chen{
5391a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#if 0
5392a695f958db37c102d480a9c0780abec262ba8332Johnny Chen    // ARM pseudo code...
5393a695f958db37c102d480a9c0780abec262ba8332Johnny Chen    if ConditionPassed() then
5394a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        EncodingSpecificOperations();
5395a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5396a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        if d == 15 then         // Can only occur for ARM encodings
5397a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            ALUWritePC(result);
5398a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        else
5399a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            R[d] = result;
5400a695f958db37c102d480a9c0780abec262ba8332Johnny Chen#endif
5401a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
5402a695f958db37c102d480a9c0780abec262ba8332Johnny Chen    bool success = false;
5403a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
54047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5405a695f958db37c102d480a9c0780abec262ba8332Johnny Chen    {
5406a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        uint32_t Rd;
5407a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5408a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        bool add;
5409a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        switch (encoding)
5410a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        {
5411a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case eEncodingT1:
5412a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            Rd = Bits32(opcode, 10, 8);
5413a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
54144a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton            add = true;
5415a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            break;
5416a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case eEncodingT2:
5417a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case eEncodingT3:
5418a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            Rd = Bits32(opcode, 11, 8);
5419a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5420a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5421a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            if (BadReg(Rd))
5422a695f958db37c102d480a9c0780abec262ba8332Johnny Chen                return false;
5423a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            break;
5424a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case eEncodingA1:
5425a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case eEncodingA2:
5426a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            Rd = Bits32(opcode, 15, 12);
5427a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5428a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5429a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            break;
5430a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        default:
5431a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            return false;
5432a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        }
5433a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
5434a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        // Read the PC value.
5435a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        uint32_t pc = ReadCoreReg(PC_REG, &success);
5436a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        if (!success)
5437a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            return false;
5438a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
5439a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5440a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
5441a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        EmulateInstruction::Context context;
5442a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
5443a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        context.SetNoArgs ();
5444a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
5445a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        if (!WriteCoreReg(context, result, Rd))
5446a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            return false;
5447a695f958db37c102d480a9c0780abec262ba8332Johnny Chen    }
5448a695f958db37c102d480a9c0780abec262ba8332Johnny Chen    return true;
5449a695f958db37c102d480a9c0780abec262ba8332Johnny Chen}
5450a695f958db37c102d480a9c0780abec262ba8332Johnny Chen
5451e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5452e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// to the destination register.  It can optionally update the condition flags based on the result.
5453e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool
54547bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5455e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{
5456e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0
5457e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    // ARM pseudo code...
5458e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if ConditionPassed() then
5459e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EncodingSpecificOperations();
5460e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        result = R[n] AND imm32;
5461e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
5462e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
5463e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        else
5464e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            R[d] = result;
5465e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if setflags then
5466e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.N = result<31>;
5467e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.Z = IsZeroBit(result);
5468e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.C = carry;
5469e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                // APSR.V unchanged
5470e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif
5471e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5472e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    bool success = false;
5473e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
54747bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5475e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    {
5476e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t Rd, Rn;
5477e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5478e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        bool setflags;
5479e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5480e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        switch (encoding)
5481e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        {
5482e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingT1:
5483e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 11, 8);
5484e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
5485e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
5486e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5487de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5488e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
54897bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateTSTImm(opcode, eEncodingT1);
5490e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5491e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                return false;
5492e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
5493e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingA1:
5494e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 15, 12);
5495e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
5496e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
5497e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
54981f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
5499e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
55001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
5501e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
5502e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        default:
5503e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5504e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        }
5505e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5506e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // Read the first operand.
5507157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
5508e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!success)
5509e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5510e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5511e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t result = val1 & imm32;
5512e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5513e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EmulateInstruction::Context context;
5514e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
5515e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.SetNoArgs ();
5516e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5517e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5518e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5519e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    }
5520e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    return true;
5521e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen}
5522e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5523e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5524e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// and writes the result to the destination register.  It can optionally update the condition flags
5525e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen// based on the result.
5526e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chenbool
55277bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5528e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen{
5529e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#if 0
5530e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    // ARM pseudo code...
5531e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    if ConditionPassed() then
5532e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EncodingSpecificOperations();
5533e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5534e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        result = R[n] AND shifted;
5535e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
5536e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
5537e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        else
5538e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            R[d] = result;
5539e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if setflags then
5540e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.N = result<31>;
5541e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.Z = IsZeroBit(result);
5542e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                APSR.C = carry;
5543e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                // APSR.V unchanged
5544e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen#endif
5545e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5546e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    bool success = false;
5547e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
55487bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5549e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    {
5550e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t Rd, Rn, Rm;
5551e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        ARM_ShifterType shift_t;
5552e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
5553e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        bool setflags;
5554e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t carry;
5555e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        switch (encoding)
5556e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        {
5557e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingT1:
5558e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
5559e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rm = Bits32(opcode, 5, 3);
5560e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = !InITBlock();
5561e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            shift_t = SRType_LSL;
5562e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            shift_n = 0;
5563ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
5564e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingT2:
5565e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 11, 8);
5566e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
5567e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rm = Bits32(opcode, 3, 0);
5568e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
55693dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5570de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            // if Rd == '1111' && S == '1' then SEE TST (register);
5571e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
55727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateTSTReg(opcode, eEncodingT2);
5573e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5574e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen                return false;
5575e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
5576e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        case eEncodingA1:
5577e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rd = Bits32(opcode, 15, 12);
5578e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rn = Bits32(opcode, 19, 16);
5579e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            Rm = Bits32(opcode, 3, 0);
5580e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            setflags = BitIsSet(opcode, 20);
55813dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
55821f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
5583e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            if (Rd == 15 && setflags)
55841f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
5585e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            break;
5586e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        default:
5587e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5588e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        }
5589e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5590e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // Read the first operand.
5591157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
5592e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!success)
5593e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5594e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5595e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // Read the second operand.
5596157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
5597e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!success)
5598e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5599e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5600a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5601a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
5602a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
5603e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        uint32_t result = val1 & shifted;
5604e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5605e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        EmulateInstruction::Context context;
5606e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
5607e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        context.SetNoArgs ();
5608e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5609e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5610e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen            return false;
5611e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    }
5612e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen    return true;
5613e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen}
5614e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen
5615b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5616b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// immediate value, and writes the result to the destination register.  It can optionally update the
5617b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// condition flags based on the result.
5618b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool
56197bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5620b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{
5621b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0
5622b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    // ARM pseudo code...
5623b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    if ConditionPassed() then
5624b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        EncodingSpecificOperations();
5625b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        result = R[n] AND NOT(imm32);
5626b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
5627b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
5628b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        else
5629b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            R[d] = result;
5630b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            if setflags then
5631b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                APSR.N = result<31>;
5632b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                APSR.Z = IsZeroBit(result);
5633b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                APSR.C = carry;
5634b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                // APSR.V unchanged
5635b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif
5636b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5637b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    bool success = false;
5638b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
56397bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5640b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    {
5641b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t Rd, Rn;
5642b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5643b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        bool setflags;
5644b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5645b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        switch (encoding)
5646b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        {
5647b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        case eEncodingT1:
5648b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rd = Bits32(opcode, 11, 8);
5649b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rn = Bits32(opcode, 19, 16);
5650b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            setflags = BitIsSet(opcode, 20);
5651b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5652b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            if (BadReg(Rd) || BadReg(Rn))
5653b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                return false;
5654b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            break;
5655b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        case eEncodingA1:
5656b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rd = Bits32(opcode, 15, 12);
5657b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rn = Bits32(opcode, 19, 16);
5658b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            setflags = BitIsSet(opcode, 20);
5659b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
56601f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
5661bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5662b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            if (Rd == 15 && setflags)
56631f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
5664b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            break;
5665b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        default:
5666b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5667b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        }
5668b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5669b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // Read the first operand.
5670b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
5671b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if (!success)
5672b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5673b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5674b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t result = val1 & ~imm32;
5675b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5676b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        EmulateInstruction::Context context;
5677b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
5678b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        context.SetNoArgs ();
5679b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5680b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5681b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5682b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    }
5683b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    return true;
5684b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen}
5685b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5686b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5687b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// optionally-shifted register value, and writes the result to the destination register.
5688b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen// It can optionally update the condition flags based on the result.
5689b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chenbool
56907bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5691b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen{
5692b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#if 0
5693b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    // ARM pseudo code...
5694b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    if ConditionPassed() then
5695b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        EncodingSpecificOperations();
5696b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5697b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        result = R[n] AND NOT(shifted);
5698b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
5699b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
5700b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        else
5701b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            R[d] = result;
5702b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            if setflags then
5703b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                APSR.N = result<31>;
5704b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                APSR.Z = IsZeroBit(result);
5705b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                APSR.C = carry;
5706b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                // APSR.V unchanged
5707b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen#endif
5708b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5709b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    bool success = false;
5710b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
57117bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5712b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    {
5713b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t Rd, Rn, Rm;
5714b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        ARM_ShifterType shift_t;
5715b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
5716b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        bool setflags;
5717b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t carry;
5718b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        switch (encoding)
5719b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        {
5720b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        case eEncodingT1:
5721b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
5722b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rm = Bits32(opcode, 5, 3);
5723b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            setflags = !InITBlock();
5724b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            shift_t = SRType_LSL;
5725b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            shift_n = 0;
5726b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            break;
5727b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        case eEncodingT2:
5728b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rd = Bits32(opcode, 11, 8);
5729b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rn = Bits32(opcode, 19, 16);
5730b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rm = Bits32(opcode, 3, 0);
5731b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            setflags = BitIsSet(opcode, 20);
5732b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5733b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5734b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen                return false;
5735b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            break;
5736b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        case eEncodingA1:
5737b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rd = Bits32(opcode, 15, 12);
5738b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rn = Bits32(opcode, 19, 16);
5739b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            Rm = Bits32(opcode, 3, 0);
5740b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            setflags = BitIsSet(opcode, 20);
5741b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
57421f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
5743bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5744b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            if (Rd == 15 && setflags)
57451f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
5746b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            break;
5747b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        default:
5748b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5749b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        }
5750b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5751b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // Read the first operand.
5752b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
5753b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if (!success)
5754b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5755b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5756b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // Read the second operand.
5757b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
5758b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if (!success)
5759b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5760b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5761a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5762a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
5763a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
5764b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        uint32_t result = val1 & ~shifted;
5765b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5766b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        EmulateInstruction::Context context;
5767b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
5768b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        context.SetNoArgs ();
5769b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
5770b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5771b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen            return false;
5772b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    }
5773b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen    return true;
5774b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen}
5775b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen
57764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5777e92b27c9262fd185359e6e2184b20d08953485f4Johnny Chen// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
57784d729c559d039181f250e0e3cd444fa73638f26fCaroline Ticebool
57797bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
57804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice{
57814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#if 0
57824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    if ConditionPassed() then
57834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        EncodingSpecificOperations();
57844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
57854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        address = if index then offset_addr else R[n];
57864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        data = MemU[address,4];
57874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if wback then R[n] = offset_addr;
57884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if t == 15 then
5789bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5790bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        elsif UnalignedSupport() || address<1:0> = '00' then
57914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            R[t] = data;
57924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else // Can only apply before ARMv7
57934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            R[t] = ROR(data, 8*UInt(address<1:0>));
57944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice#endif
57954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
57964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    bool success = false;
57974d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
57987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
57994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    {
58004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
58014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58024d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint32_t t;
58034d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint32_t n;
58044d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint32_t imm32;
58054d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        bool index;
58064d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        bool add;
58074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        bool wback;
58084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        switch (encoding)
58104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
58114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            case eEncodingA1:
5812bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDR (literal);
5813bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRT;
5814bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
58154d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
58164d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                t = Bits32 (opcode, 15, 12);
58174d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                n = Bits32 (opcode, 19, 16);
58184d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
58194d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
5820bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5821bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                index = BitIsSet (opcode, 24);
5822bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                add = BitIsSet (opcode, 23);
5823bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
58244d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58254d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // if wback && n == t then UNPREDICTABLE;
58264d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                if (wback && (n == t))
58274d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                    return false;
58284d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58294d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                break;
58304d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58314d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            default:
58324d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
58334d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
58344d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58354d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        addr_t address;
58364d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        addr_t offset_addr;
58378d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice        addr_t base_address = ReadCoreReg (n, &success);
58384d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (!success)
58394d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            return false;
58404d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58414d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
58424d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (add)
58438d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice            offset_addr = base_address + imm32;
58444d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else
58454d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            offset_addr = base_address - imm32;
58464d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58474d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // address = if index then offset_addr else R[n];
58484d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (index)
58494d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            address = offset_addr;
58504d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else
58514d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            address = base_address;
58524d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58534d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // data = MemU[address,4];
58544d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
5855c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
5856c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
58574d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58584d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        EmulateInstruction::Context context;
58594d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        context.type = eContextRegisterLoad;
58604d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - base_address);
58614d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58624d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
58634d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (!success)
58644d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            return false;
58654d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58664d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // if wback then R[n] = offset_addr;
58674d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (wback)
58684d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
58694d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.type = eContextAdjustBaseRegister;
58704d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.SetAddress (offset_addr);
58714d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
58724d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
58734d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
58744d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
58754d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // if t == 15 then
58764d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        if (t == 15)
58774d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
5878bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
58794d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (BitIsClear (address, 1) && BitIsClear (address, 0))
58804d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            {
58814d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                // LoadWritePC (data);
58824d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                context.type = eContextRegisterLoad;
58834d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                context.SetRegisterPlusOffset (base_reg, address - base_address);
58844d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                LoadWritePC (context, data);
58854d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            }
58864d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            else
58874d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                  return false;
58884d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
5889bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // elsif UnalignedSupport() || address<1:0> = '00' then
58904d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
58914d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
58924d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            // R[t] = data;
58934d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.type = eContextRegisterLoad;
58944d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - base_address);
58954d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
58964d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
58974d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
58984d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        // else // Can only apply before ARMv7
58994d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        else
59004d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        {
59014d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            // R[t] = ROR(data, 8*UInt(address<1:0>));
5902a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            data = ROR (data, Bits32 (address, 1, 0), &success);
5903a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            if (!success)
5904a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen                return false;
59054d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.type = eContextRegisterLoad;
59064d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            context.SetImmediate (data);
59074d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
59084d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice                return false;
59094d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice        }
59104d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
59114d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    }
59124d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice    return true;
59134d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice}
59144d729c559d039181f250e0e3cd444fa73638f26fCaroline Tice
5915fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5916fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5917fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Ticebool
59187bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5919fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice{
5920fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#if 0
5921fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    if ConditionPassed() then
5922fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5923fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5924fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5925fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        address = if index then offset_addr else R[n];
5926fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        data = MemU[address,4];
5927fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if wback then R[n] = offset_addr;
5928fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if t == 15 then
5929bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5930bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        elsif UnalignedSupport() || address<1:0> = '00' then
5931fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            R[t] = data;
5932fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else // Can only apply before ARMv7
5933fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if CurrentInstrSet() == InstrSet_ARM then
5934fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                R[t] = ROR(data, 8*UInt(address<1:0>));
5935fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
5936fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                R[t] = bits(32) UNKNOWN;
5937fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice#endif
5938fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5939fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    bool success = false;
5940fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
59417bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
5942fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    {
5943fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
5944fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5945fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t t;
5946fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t n;
5947fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t m;
5948fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        bool index;
5949fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        bool add;
5950fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        bool wback;
5951fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        ARM_ShifterType shift_t;
5952fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t shift_n;
5953fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5954fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        switch (encoding)
5955fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
5956fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            case eEncodingT1:
5957fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5958fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5959fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                t = Bits32 (opcode, 2, 0);
5960fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                n = Bits32 (opcode, 5, 3);
5961fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                m = Bits32 (opcode, 8, 6);
5962fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5963fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
5964fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                index = true;
5965fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                add = true;
5966fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                wback = false;
5967fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5968fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
5969fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_t = SRType_LSL;
5970fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_n = 0;
5971fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5972fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                break;
5973fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5974fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            case eEncodingT2:
5975bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDR (literal);
5976fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5977fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                t = Bits32 (opcode, 15, 12);
5978fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                n = Bits32 (opcode, 19, 16);
5979fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                m = Bits32 (opcode, 3, 0);
5980fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5981fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
5982fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                index = true;
5983fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                add = true;
5984fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                wback = false;
5985fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5986fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5987fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_t = SRType_LSL;
5988fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
5989fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5990fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if BadReg(m) then UNPREDICTABLE;
5991fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (BadReg (m))
5992fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5993fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5994fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5995fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if ((t == 15) && InITBlock() && !LastInITBlock())
5996fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
5997fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
5998fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                break;
5999fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6000fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            case eEncodingA1:
6001fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
6002bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRT;
6003fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6004fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                t = Bits32 (opcode, 15, 12);
6005fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                n = Bits32 (opcode, 19, 16);
6006fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                m = Bits32 (opcode, 3, 0);
6007fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6008bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6009fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                index = BitIsSet (opcode, 24);
6010fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                add = BitIsSet (opcode, 23);
6011fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6012fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6013fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6014fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                uint32_t type = Bits32 (opcode, 6, 5);
6015fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
6016fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                shift_n = DecodeImmShift (type, imm5, shift_t);
6017fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6018fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if m == 15 then UNPREDICTABLE;
6019fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (m == 15)
6020fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
6021fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6022fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6023fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (wback && ((n == 15) || (n == t)))
6024fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
6025fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
6026fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                break;
6027fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6028fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6029fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            default:
6030fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
6031fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
6032fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6033fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6034fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (!success)
6035fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            return false;
6036fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6037fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6038fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (!success)
6039fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            return false;
6040fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6041fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        addr_t offset_addr;
6042fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        addr_t address;
6043fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6044fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6045a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6046a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
6047a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
6048fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6049fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6050fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (add)
6051fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            offset_addr = Rn + offset;
6052fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else
6053fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            offset_addr = Rn - offset;
6054fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6055fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // address = if index then offset_addr else R[n];
6056fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (index)
6057fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                address = offset_addr;
6058fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
6059fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                address = Rn;
6060fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6061fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // data = MemU[address,4];
6062c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
6063c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6064fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6065fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        EmulateInstruction::Context context;
6066fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        context.type = eContextRegisterLoad;
6067fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
6068fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6069fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6070fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (!success)
6071fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            return false;
6072fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6073fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // if wback then R[n] = offset_addr;
6074fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (wback)
6075fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
6076fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.type = eContextAdjustBaseRegister;
6077fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.SetAddress (offset_addr);
6078fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6079fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
6080fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
6081fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6082fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        // if t == 15 then
6083fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        if (t == 15)
6084fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
6085bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6086fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (BitIsClear (address, 1) && BitIsClear (address, 0))
6087fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
6088fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.type = eContextRegisterLoad;
6089fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.SetRegisterPlusOffset (base_reg, address - Rn);
6090fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                LoadWritePC (context, data);
6091fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
6092fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
6093fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
6094fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
6095bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // elsif UnalignedSupport() || address<1:0> = '00' then
6096fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6097fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
6098fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            // R[t] = data;
6099fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.type = eContextRegisterLoad;
6100fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - Rn);
6101fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6102fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                return false;
6103fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
6104fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        else // Can only apply before ARMv7
6105fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        {
6106fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            // if CurrentInstrSet() == InstrSet_ARM then
6107fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            if (CurrentInstrSet () == eModeARM)
6108fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
6109fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // R[t] = ROR(data, 8*UInt(address<1:0>));
6110a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen                data = ROR (data, Bits32 (address, 1, 0), &success);
6111a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen                if (!success)
6112a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen                    return false;
6113fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.type = eContextRegisterLoad;
6114fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                context.SetImmediate (data);
6115fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6116fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                    return false;
6117fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
6118fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            else
6119fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            {
6120fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                // R[t] = bits(32) UNKNOWN;
6121fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice                WriteBits32Unknown (t);
6122fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice            }
6123fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice        }
6124fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    }
6125fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice    return true;
6126fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice}
612721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
612821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice// LDRB (immediate, Thumb)
612921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Ticebool
61307bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
613121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice{
613221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#if 0
613321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    if ConditionPassed() then
613421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
613521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
613621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        address = if index then offset_addr else R[n];
613721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        R[t] = ZeroExtend(MemU[address,1], 32);
613821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if wback then R[n] = offset_addr;
613921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice#endif
614021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
614121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    bool success = false;
614221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
61437bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
614421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    {
614521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t t;
614621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t n;
614721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t imm32;
614821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        bool index;
614921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        bool add;
615021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        bool wback;
615121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
615221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
615321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        switch (encoding)
615421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        {
615521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            case eEncodingT1:
615621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
615721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                t = Bits32 (opcode, 2, 0);
615821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                n = Bits32 (opcode, 5, 3);
615921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                imm32 = Bits32 (opcode, 10, 6);
616021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
616121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
616221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                index = true;
616321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                add = true;
616421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                wback= false;
616521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
616621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                break;
616721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
616821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            case eEncodingT2:
6169bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE PLD;
6170bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRB (literal);
617121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
617221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                t = Bits32 (opcode, 15, 12);
617321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                n = Bits32 (opcode, 19, 16);
617421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
617521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
617621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
617721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                index = true;
617821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                add = true;
617921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                wback = false;
618021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
618121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if t == 13 then UNPREDICTABLE;
618221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                if (t == 13)
618321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                    return false;
618421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
618521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                break;
618621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
618721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            case eEncodingT3:
6188bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6189bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRB (literal);
6190bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6191bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '0' then UNDEFINED;
619221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
619321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                    return false;
619421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
619521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
619621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                t = Bits32 (opcode, 15, 12);
619721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                n = Bits32 (opcode, 19, 16);
619821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                imm32 = Bits32 (opcode, 7, 0);
619921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
6200bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
620121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                index = BitIsSet (opcode, 10);
620221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                add = BitIsSet (opcode, 9);
620321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                wback = BitIsSet (opcode, 8);
620421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
620521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
620621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                if (BadReg (t) || (wback && (n == t)))
620721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                    return false;
620821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
620921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                break;
621021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
621121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            default:
621221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                return false;
621321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        }
621421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
621521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
621621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (!success)
621721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            return false;
621821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
621921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        addr_t address;
622021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        addr_t offset_addr;
622121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
622221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
622321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (add)
622421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            offset_addr = Rn + imm32;
622521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        else
622621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            offset_addr = Rn - imm32;
622721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
622821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // address = if index then offset_addr else R[n];
622921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (index)
623021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            address = offset_addr;
623121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        else
623221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            address = Rn;
623321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
623421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // R[t] = ZeroExtend(MemU[address,1], 32);
6235c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
6236c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
6237c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6238c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
623921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
624021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        EmulateInstruction::Context context;
624121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        context.type = eContextRegisterLoad;
624221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
624321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
624421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        uint64_t data = MemURead (context, address, 1, 0, &success);
624521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (!success)
624621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            return false;
624721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
624821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
624921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            return false;
625021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice
625121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        // if wback then R[n] = offset_addr;
625221b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        if (wback)
625321b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        {
625421b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            context.type = eContextAdjustBaseRegister;
625521b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            context.SetAddress (offset_addr);
625621b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
625721b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice                return false;
625821b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice        }
625921b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    }
626021b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice    return true;
626121b604bbe9b0c6e1ebd275c1beff24aa2fa8732cCaroline Tice}
6262f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6263f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6264f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice// zero-extends it to form a 32-bit word and writes it to a register.
6265f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Ticebool
62667bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6267f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice{
6268f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#if 0
6269f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    if ConditionPassed() then
6270f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6271f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        base = Align(PC,4);
6272f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        address = if add then (base + imm32) else (base - imm32);
6273f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        R[t] = ZeroExtend(MemU[address,1], 32);
6274f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice#endif
6275f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6276f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    bool success = false;
6277f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
62787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
6279f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    {
6280f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t t;
6281f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t imm32;
6282f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        bool add;
6283f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        switch (encoding)
6284f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        {
6285f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            case eEncodingT1:
6286bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE PLD;
6287bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6288f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                t = Bits32 (opcode, 15, 12);
6289f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
6290f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                add = BitIsSet (opcode, 23);
6291f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6292f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // if t == 13 then UNPREDICTABLE;
6293f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                if (t == 13)
6294f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                    return false;
6295f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6296f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                break;
6297f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6298f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            case eEncodingA1:
6299bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6300f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                t = Bits32 (opcode, 15, 12);
6301f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
6302f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                add = BitIsSet (opcode, 23);
6303f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6304f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                // if t == 15 then UNPREDICTABLE;
6305f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                if (t == 15)
6306f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                    return false;
6307f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                break;
6308f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6309f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            default:
6310f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice                return false;
6311f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        }
6312f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6313f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        // base = Align(PC,4);
63148d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6315f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (!success)
6316f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            return false;
6317f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6318f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint32_t base = AlignPC (pc_val);
6319f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6320f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        addr_t address;
6321f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        // address = if add then (base + imm32) else (base - imm32);
6322f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (add)
6323f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            address = base + imm32;
6324f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        else
6325f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            address = base - imm32;
6326f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6327f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        // R[t] = ZeroExtend(MemU[address,1], 32);
6328f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        EmulateInstruction::Context context;
6329f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        context.type = eContextRelativeBranchImmediate;
6330f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        context.SetImmediate (address - base);
6331f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6332f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        uint64_t data = MemURead (context, address, 1, 0, &success);
6333f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (!success)
6334f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            return false;
6335f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice
6336f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6337f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice            return false;
6338f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    }
6339f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice    return true;
6340f55261f53d56b4911c4c1ce419d893e5250d7150Caroline Tice}
634130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
634230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
634330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
634430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice// optionally be shifted.
634530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Ticebool
63467bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
634730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice{
634830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#if 0
634930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    if ConditionPassed() then
635030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
635130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
635230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
635330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        address = if index then offset_addr else R[n];
635430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        R[t] = ZeroExtend(MemU[address,1],32);
635530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if wback then R[n] = offset_addr;
635630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice#endif
635730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
635830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    bool success = false;
635930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
63607bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
636130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    {
636230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t t;
636330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t n;
636430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t m;
636530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        bool index;
636630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        bool add;
636730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        bool wback;
636830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        ARM_ShifterType shift_t;
636930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t shift_n;
637030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
637130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
637230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        switch (encoding)
637330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        {
637430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            case eEncodingT1:
637530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
637630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                t = Bits32 (opcode, 2, 0);
637730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                n = Bits32 (opcode, 5, 3);
637830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                m = Bits32 (opcode, 8, 6);
637930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
638030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
638130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                index = true;
638230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                add = true;
638330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                wback = false;
638430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
638530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
638630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_t = SRType_LSL;
638730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_n = 0;
638830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                break;
638930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
639030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            case eEncodingT2:
6391bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE PLD;
6392bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRB (literal);
639330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
639430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                t = Bits32 (opcode, 15, 12);
639530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                n = Bits32 (opcode, 19, 16);
639630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                m = Bits32 (opcode, 3, 0);
639730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
639830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
639930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                index = true;
640030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                add = true;
640130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                wback = false;
640230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
640330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
640430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_t = SRType_LSL;
640530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
640630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
640730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if t == 13 || BadReg(m) then UNPREDICTABLE;
640830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                if ((t == 13) || BadReg (m))
640930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                    return false;
641030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                break;
641130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
641230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            case eEncodingA1:
641330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            {
6414bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRBT;
641530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
641630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                t = Bits32 (opcode, 15, 12);
641730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                n = Bits32 (opcode, 19, 16);
641830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                m = Bits32 (opcode, 3, 0);
641930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
6420bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
642130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                index = BitIsSet (opcode, 24);
642230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                add = BitIsSet (opcode, 23);
642330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
642430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
642530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
642630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                uint32_t type = Bits32 (opcode, 6, 5);
642730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                uint32_t imm5 = Bits32 (opcode, 11, 7);
642830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                shift_n = DecodeImmShift (type, imm5, shift_t);
642930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
643030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if t == 15 || m == 15 then UNPREDICTABLE;
643130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                if ((t == 15) || (m == 15))
643230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                    return false;
643330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
643430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
643530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                if (wback && ((n == 15) || (n == t)))
643630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                    return false;
643730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            }
643830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                break;
643930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
644030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            default:
644130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                return false;
644230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        }
644330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
644430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        addr_t offset_addr;
644530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        addr_t address;
644630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
644730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
644830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
644930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!success)
645030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
645130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
6452a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6453a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
6454a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
645530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
645630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
645730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
645830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!success)
645930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
646030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
646130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (add)
646230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            offset_addr = Rn + offset;
646330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        else
646430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            offset_addr = Rn - offset;
646530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
646630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // address = if index then offset_addr else R[n];
646730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (index)
646830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            address = offset_addr;
646930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        else
647030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            address = Rn;
647130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
647230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // R[t] = ZeroExtend(MemU[address,1],32);
6473c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
6474c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
647530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
647630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        EmulateInstruction::Context context;
647730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        context.type = eContextRegisterLoad;
647830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
647930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
648030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        uint64_t data = MemURead (context, address, 1, 0, &success);
648130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!success)
648230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
648330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
648430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
648530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            return false;
648630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice
648730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        // if wback then R[n] = offset_addr;
648830fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        if (wback)
648930fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        {
649030fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            context.type = eContextAdjustBaseRegister;
649130fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            context.SetAddress (offset_addr);
649230fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
649330fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice                return false;
649430fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice        }
649530fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    }
649630fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice    return true;
649730fec12a2c2f0fe75c78e9b9f791bc53cd92cdfdCaroline Tice}
64980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
64990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
65000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
65010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice// post-indexed, or pre-indexed addressing.
65020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Ticebool
65037bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
65040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice{
65050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#if 0
65060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice    if ConditionPassed() then
65070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
65080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
65090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        address = if index then offset_addr else R[n];
65100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        data = MemU[address,2];
65110491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if wback then R[n] = offset_addr;
6512bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> = '0' then
65130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            R[t] = ZeroExtend(data, 32);
65140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        else // Can only apply before ARMv7
65150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            R[t] = bits(32) UNKNOWN;
65160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice#endif
65170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice    bool success = false;
65200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65217bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
65220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice    {
65230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        uint32_t t;
65240491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        uint32_t n;
65250491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        uint32_t imm32;
65260491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        bool index;
65270491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        bool add;
65280491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        bool wback;
65290491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65300491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
65310491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        switch (encoding)
65320491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        {
65330491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            case eEncodingT1:
6534bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
65350491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                t = Bits32 (opcode, 2, 0);
65360491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                n = Bits32 (opcode, 5, 3);
65370491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                imm32 = Bits32 (opcode, 10, 6) << 1;
65380491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65390491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
65400491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                index = true;
65410491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                add = true;
65420491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                wback = false;
65430491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65440491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                break;
65450491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65460491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            case eEncodingT2:
6547bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE "Unallocated memory hints";
6548bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRH (literal);
65490491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
65500491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                t = Bits32 (opcode, 15, 12);
65510491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                n = Bits32 (opcode, 19, 16);
65520491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
65530491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65540491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
65550491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                index = true;
65560491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                add = true;
65570491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                wback = false;
65580491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65590491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                // if t == 13 then UNPREDICTABLE;
65600491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                if (t == 13)
65610491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                    return false;
65620491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                break;
65630491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65640491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            case eEncodingT3:
6565bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRH (literal);
6566bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6567bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6568bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '0' then UNDEFINED;
65690491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
65700491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                    return false;
65710491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65720491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
65730491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                t = Bits32 (opcode, 15, 12);
65740491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                n = Bits32 (opcode, 19, 16);
65750491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                imm32 = Bits32 (opcode, 7, 0);
65760491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
6577bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
65780491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                index = BitIsSet (opcode, 10);
65790491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                add = BitIsSet (opcode, 9);
65800491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                wback = BitIsSet (opcode, 8);
65810491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65820491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
65830491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                if (BadReg (t) || (wback && (n == t)))
65840491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                    return false;
65850491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                break;
65860491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65870491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            default:
65880491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                return false;
65890491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        }
65900491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65910491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
65920491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
65930491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if (!success)
65940491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            return false;
65950491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65960491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        addr_t offset_addr;
65970491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        addr_t address;
65980491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
65990491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if (add)
66000491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            offset_addr = Rn + imm32;
66010491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        else
66020491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            offset_addr = Rn - imm32;
66030491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
66040491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        // address = if index then offset_addr else R[n];
66050491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if (index)
66060491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            address = offset_addr;
66070491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        else
66080491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            address = Rn;
66090491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
66100491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        // data = MemU[address,2];
6611c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
6612c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
66130491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
66140491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        EmulateInstruction::Context context;
66150491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        context.type = eContextRegisterLoad;
66160491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
66170491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
66180491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        uint64_t data = MemURead (context, address, 2, 0, &success);
66190491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if (!success)
66200491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            return false;
66210491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
66220491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        // if wback then R[n] = offset_addr;
66230491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if (wback)
66240491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        {
66250491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            context.type = eContextAdjustBaseRegister;
66260491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            context.SetAddress (offset_addr);
66270491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
66280491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                return false;
66290491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        }
66300491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice
6631bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> = '0' then
66320491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        if (UnalignedSupport () || BitIsClear (address, 0))
66330491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        {
66340491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            // R[t] = ZeroExtend(data, 32);
66350491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            context.type = eContextRegisterLoad;
66360491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - Rn);
66370491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
66380491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice                return false;
66390491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        }
66400491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        else // Can only apply before ARMv7
66410491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        {
66420491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            // R[t] = bits(32) UNKNOWN;
66430491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice            WriteBits32Unknown (t);
66440491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice        }
66450491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice    }
66460491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice    return true;
66470491b3b75e1b045ab548f77fd1f76035522debdeCaroline Tice}
6648fe4791199f5eb55a1ceecff58364fcbdb2e8cfaaCaroline Tice
6649952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6650952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice// zero-extends it to form a 32-bit word, and writes it to a register.
6651952b53892191222c56003cd60d8a4a71c4384aa7Caroline Ticebool
66527bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6653952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice{
6654952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#if 0
6655952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice    if ConditionPassed() then
6656952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6657952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        base = Align(PC,4);
6658952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        address = if add then (base + imm32) else (base - imm32);
6659952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        data = MemU[address,2];
6660bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> = '0' then
6661952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            R[t] = ZeroExtend(data, 32);
6662952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        else // Can only apply before ARMv7
6663952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            R[t] = bits(32) UNKNOWN;
6664952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice#endif
66650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
6666952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice    bool success = false;
6667952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
66687bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
6669952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice    {
6670952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        uint32_t t;
6671952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        uint32_t imm32;
6672952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        bool add;
6673952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6674952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6675952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        switch (encoding)
6676952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        {
6677952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            case eEncodingT1:
6678bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE "Unallocated memory hints";
6679bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6680952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                t = Bits32 (opcode, 15, 12);
6681952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
6682952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                add = BitIsSet (opcode, 23);
6683952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6684952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                // if t == 13 then UNPREDICTABLE;
6685952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                if (t == 13)
6686952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                    return false;
6687952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6688952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                break;
6689952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6690952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            case eEncodingA1:
6691952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            {
6692952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                uint32_t imm4H = Bits32 (opcode, 11, 8);
6693952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                uint32_t imm4L = Bits32 (opcode, 3, 0);
6694952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6695bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6696952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                t = Bits32 (opcode, 15, 12);
669740b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice                imm32 = (imm4H << 4) | imm4L;
6698952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                add = BitIsSet (opcode, 23);
6699952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6700952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                // if t == 15 then UNPREDICTABLE;
6701952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                if (t == 15)
6702952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                    return false;
6703952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                break;
6704952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            }
6705952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6706952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            default:
6707952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                return false;
6708952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        }
6709952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6710952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        // base = Align(PC,4);
67118d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6712952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        if (!success)
6713952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            return false;
6714952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6715952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        addr_t base = AlignPC (pc_value);
6716952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        addr_t address;
6717952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6718952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        // address = if add then (base + imm32) else (base - imm32);
6719952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        if (add)
6720952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            address = base + imm32;
6721952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        else
6722952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            address = base - imm32;
6723952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6724952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        // data = MemU[address,2];
6725c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
6726c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6727952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6728952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        EmulateInstruction::Context context;
6729952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        context.type = eContextRegisterLoad;
6730952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        context.SetRegisterPlusOffset (base_reg, address - base);
6731952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6732952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        uint64_t data = MemURead (context, address, 2, 0, &success);
6733952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        if (!success)
6734952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            return false;
6735952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6736952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6737bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> = '0' then
6738952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        if (UnalignedSupport () || BitIsClear (address, 0))
6739952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        {
6740952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            // R[t] = ZeroExtend(data, 32);
6741952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            context.type = eContextRegisterLoad;
6742952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            context.SetRegisterPlusOffset (base_reg, address - base);
6743952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6744952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice                return false;
6745952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
6746952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        }
6747952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        else // Can only apply before ARMv7
6748952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        {
6749952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            // R[t] = bits(32) UNKNOWN;
6750952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice            WriteBits32Unknown (t);
6751952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice        }
6752952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice    }
6753952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice    return true;
6754952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice}
6755952b53892191222c56003cd60d8a4a71c4384aa7Caroline Tice
67560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
67570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
67580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice// be shifted left by 0, 1, 2, or 3 bits.
67590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Ticebool
67607bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
67610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice{
67620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#if 0
67630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice    if ConditionPassed() then
67640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
67650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
67660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
67670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        address = if index then offset_addr else R[n];
67680e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        data = MemU[address,2];
67690e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if wback then R[n] = offset_addr;
6770bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> = '0' then
67710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            R[t] = ZeroExtend(data, 32);
67720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        else // Can only apply before ARMv7
67730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            R[t] = bits(32) UNKNOWN;
67740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice#endif
67750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
67760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice    bool success = false;
67770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
67787bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
67790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice    {
67800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint32_t t;
67810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint32_t n;
67820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint32_t m;
67830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        bool index;
67840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        bool add;
67850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        bool wback;
67860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        ARM_ShifterType shift_t;
67870e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint32_t shift_n;
67880e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
67890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
67900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        switch (encoding)
67910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        {
67920e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            case eEncodingT1:
67930e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
67940e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
67950e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                t = Bits32 (opcode, 2, 0);
67960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                n = Bits32 (opcode, 5, 3);
67970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                m = Bits32 (opcode, 8, 6);
67980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
67990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
68000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                index = true;
68010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                add = true;
68020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                wback = false;
68030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
68050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                shift_t = SRType_LSL;
68060e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                shift_n = 0;
68070e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68080e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                break;
68090e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68100e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            case eEncodingT2:
6811bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRH (literal);
6812bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE "Unallocated memory hints";
68130e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
68140e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                t = Bits32 (opcode, 15, 12);
68150e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                n = Bits32 (opcode, 19, 16);
68160e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                m = Bits32 (opcode, 3, 0);
68170e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68180e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
68190e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                index = true;
68200e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                add = true;
68210e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                wback = false;
68220e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68230e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
68240e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                shift_t = SRType_LSL;
68250e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                shift_n = Bits32 (opcode, 5, 4);
68260e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68270e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // if t == 13 || BadReg(m) then UNPREDICTABLE;
68280e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                if ((t == 13) || BadReg (m))
68290e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                    return false;
68300e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                break;
68310e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68320e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            case eEncodingA1:
6833bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRHT;
68340e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
68350e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                t = Bits32 (opcode, 15, 12);
68360e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                n = Bits32 (opcode, 19, 16);
68370e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                m = Bits32 (opcode, 3, 0);
68380e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
6839bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
68400e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                index = BitIsSet (opcode, 24);
68410e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                add = BitIsSet (opcode, 23);
68420e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
68430e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68440e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
68450e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                shift_t = SRType_LSL;
68460e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                shift_n = 0;
68470e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68480e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // if t == 15 || m == 15 then UNPREDICTABLE;
68490e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                if ((t == 15) || (m == 15))
68500e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                    return false;
68510e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68520e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
68530e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                if (wback && ((n == 15) || (n == t)))
68540e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                    return false;
68550e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68560e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                break;
68570e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68580e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            default:
68590e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                return false;
68600e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        }
68610e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68620e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
68630e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68640e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
68650e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (!success)
68660e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            return false;
68670e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
6868a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6869a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
6870a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
68710e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68720e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        addr_t offset_addr;
68730e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        addr_t address;
68740e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68750e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
68760e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
68770e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (!success)
68780e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            return false;
68790e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (add)
68810e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            offset_addr = Rn + offset;
68820e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        else
68830e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            offset_addr = Rn - offset;
68840e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68850e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        // address = if index then offset_addr else R[n];
68860e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (index)
68870e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            address = offset_addr;
68880e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        else
68890e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            address = Rn;
68900e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68910e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        // data = MemU[address,2];
6892c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
6893c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo offset_reg;
6894c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6895c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
68960e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
68970e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        EmulateInstruction::Context context;
68980e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        context.type = eContextRegisterLoad;
68990e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
69000e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        uint64_t data = MemURead (context, address, 2, 0, &success);
69010e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (!success)
69020e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            return false;
69030e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
69040e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        // if wback then R[n] = offset_addr;
69050e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (wback)
69060e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        {
69070e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            context.type = eContextAdjustBaseRegister;
69080e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            context.SetAddress (offset_addr);
69090e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
69100e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                return false;
69110e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        }
69120e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
6913bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> = '0' then
69140e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        if (UnalignedSupport() || BitIsClear (address, 0))
69150e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        {
69160e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            // R[t] = ZeroExtend(data, 32);
69170e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            context.type = eContextRegisterLoad;
69180e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
69190e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
69200e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice                return false;
69210e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        }
69220e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        else // Can only apply before ARMv7
69230e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        {
69240e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            // R[t] = bits(32) UNKNOWN;
69250e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice            WriteBits32Unknown (t);
69260e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice        }
69270e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice    }
69280e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice    return true;
69290e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice}
69300e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
6931a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6932a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6933a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice// or pre-indexed addressing.
6934a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Ticebool
69357bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6936a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice{
6937a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#if 0
6938a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice    if ConditionPassed() then
6939a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6940a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6941a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        address = if index then offset_addr else R[n];
6942a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        R[t] = SignExtend(MemU[address,1], 32);
6943a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if wback then R[n] = offset_addr;
6944a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice#endif
6945a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6946a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice    bool success = false;
6947a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
69487bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
6949a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice    {
6950a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        uint32_t t;
6951a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        uint32_t n;
6952a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        uint32_t imm32;
6953a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        bool index;
6954a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        bool add;
6955a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        bool wback;
6956a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6957a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6958a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        switch (encoding)
6959a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        {
6960a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            case eEncodingT1:
6961bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE PLI;
6962bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSB (literal);
6963a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6964a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                t = Bits32 (opcode, 15, 12);
6965a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                n = Bits32 (opcode, 19, 16);
6966a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
6967a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6968a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
6969a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                index = true;
6970a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                add = true;
6971a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                wback = false;
6972a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6973a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // if t == 13 then UNPREDICTABLE;
6974a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                if (t == 13)
6975a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                    return false;
6976a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6977a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                break;
6978a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6979a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            case eEncodingT2:
6980bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6981bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSB (literal);
6982bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6983bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '0' then UNDEFINED;
6984a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6985a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                    return false;
6986a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6987a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6988a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                t = Bits32 (opcode, 15, 12);
6989a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                n = Bits32 (opcode, 19, 16);
6990a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
6991a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6992bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6993a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                index = BitIsSet (opcode, 10);
6994a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                add = BitIsSet (opcode, 9);
6995a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                wback = BitIsSet (opcode, 8);
6996a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
6997a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6998bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                  if (((t == 13) || ((t == 15)
6999bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7000bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                      || (wback && (n == t)))
7001a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                    return false;
7002a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7003a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                break;
7004a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7005a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            case eEncodingA1:
7006a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            {
7007bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSB (literal);
7008bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRSBT;
7009a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7010a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                t = Bits32 (opcode, 15, 12);
7011a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                n = Bits32 (opcode, 19, 16);
7012a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7013a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                uint32_t imm4H = Bits32 (opcode, 11, 8);
7014a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                uint32_t imm4L = Bits32 (opcode, 3, 0);
701540b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice                imm32 = (imm4H << 4) | imm4L;
7016a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7017bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7018a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                index = BitIsSet (opcode, 24);
7019a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                add = BitIsSet (opcode, 23);
7020a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7021a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7022a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7023a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                if ((t == 15) || (wback && (n == t)))
7024a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                    return false;
7025a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7026a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                break;
7027a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            }
7028a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7029a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            default:
7030a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                return false;
7031a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        }
7032a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7033bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        uint64_t Rn = ReadCoreReg (n, &success);
7034a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if (!success)
7035a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            return false;
7036a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7037a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        addr_t offset_addr;
7038a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        addr_t address;
7039a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7040a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7041a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if (add)
7042a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            offset_addr = Rn + imm32;
7043a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        else
7044a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            offset_addr = Rn - imm32;
7045a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7046a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        // address = if index then offset_addr else R[n];
7047a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if (index)
7048a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            address = offset_addr;
7049a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        else
7050a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            address = Rn;
7051a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7052a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        // R[t] = SignExtend(MemU[address,1], 32);
7053c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
7054c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7055a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7056a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        EmulateInstruction::Context context;
7057a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        context.type = eContextRegisterLoad;
7058a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
7059a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7060a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7061a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if (!success)
7062a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            return false;
7063a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7064a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7065a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7066a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            return false;
7067a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7068a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        // if wback then R[n] = offset_addr;
7069a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        if (wback)
7070a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        {
7071a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            context.type = eContextAdjustBaseRegister;
7072a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            context.SetAddress (offset_addr);
7073a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7074a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice                return false;
7075a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice        }
7076a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice    }
7077a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice
7078a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice    return true;
7079a5e28af7d3ebf0820c62f08c9d0e194767586808Caroline Tice}
70800e6bc95dceb0bd29b0029771840e8afc690fe6c1Caroline Tice
70815f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
70825f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice// sign-extends it to form a 32-bit word, and writes tit to a register.
70835f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Ticebool
70847bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
70855f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice{
70865f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#if 0
70875f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice    if ConditionPassed() then
70885f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
70895f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        base = Align(PC,4);
70905f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        address = if add then (base + imm32) else (base - imm32);
70915f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        R[t] = SignExtend(MemU[address,1], 32);
70925f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice#endif
70935f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
70945f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice    bool success = false;
70955f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
70967bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
70975f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice    {
70985f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        uint32_t t;
70995f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        uint32_t imm32;
71005f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        bool add;
71015f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71025f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
71035f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        switch (encoding)
71045f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        {
71055f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            case eEncodingT1:
7106bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE PLI;
7107bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
71085f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                t = Bits32 (opcode, 15, 12);
71095f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
71105f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                add = BitIsSet (opcode, 23);
71115f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71125f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                // if t == 13 then UNPREDICTABLE;
71135f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                if (t == 13)
71145f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                    return false;
71155f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71165f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                break;
71175f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71185f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            case eEncodingA1:
71195f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            {
7120bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
71215f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                t = Bits32 (opcode, 15, 12);
71225f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                uint32_t imm4H = Bits32 (opcode, 11, 8);
71235f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                uint32_t imm4L = Bits32 (opcode, 3, 0);
712440b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice                imm32 = (imm4H << 4) | imm4L;
71255f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                add = BitIsSet (opcode, 23);
71265f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71275f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                // if t == 15 then UNPREDICTABLE;
71285f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                if (t == 15)
71295f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                    return false;
71305f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71315f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                break;
71325f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            }
71335f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71345f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            default:
71355f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice                return false;
71365f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        }
71375f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71385f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        // base = Align(PC,4);
71398d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
71405f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        if (!success)
71415f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            return false;
71425f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        uint64_t base = AlignPC (pc_value);
71435f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71445f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        // address = if add then (base + imm32) else (base - imm32);
71455f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        addr_t address;
71465f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        if (add)
71475f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            address = base + imm32;
71485f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        else
71495f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            address = base - imm32;
71505f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71515f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        // R[t] = SignExtend(MemU[address,1], 32);
7152c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
7153c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
71545f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71555f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        EmulateInstruction::Context context;
71565f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        context.type = eContextRegisterLoad;
71575f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        context.SetRegisterPlusOffset (base_reg, address - base);
71585f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71595f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
71605f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        if (!success)
71615f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            return false;
71625f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
71635f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
71645f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
71655f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice            return false;
71665f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice    }
71675f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice    return true;
71685f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice}
71695f593915eac4dabdb0c38352b2fd551037e5cc20Caroline Tice
7170672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7171672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7172672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice// shifted left by 0, 1, 2, or 3 bits.
7173672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Ticebool
71747bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7175672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice{
7176672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#if 0
7177672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice    if ConditionPassed() then
7178672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7179672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7180672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7181672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        address = if index then offset_addr else R[n];
7182672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        R[t] = SignExtend(MemU[address,1], 32);
7183672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if wback then R[n] = offset_addr;
7184672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice#endif
7185672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7186672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice    bool success = false;
7187672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
71887bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
7189672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice    {
7190672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint32_t t;
7191672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint32_t n;
7192672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint32_t m;
7193672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        bool index;
7194672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        bool add;
7195672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        bool wback;
7196672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        ARM_ShifterType shift_t;
7197672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint32_t shift_n;
7198672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7199672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7200672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        switch (encoding)
7201672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        {
7202672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            case eEncodingT1:
7203672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7204672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                t = Bits32 (opcode, 2, 0);
7205672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                n = Bits32 (opcode, 5, 3);
7206672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                m = Bits32 (opcode, 8, 6);
7207672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7208672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
7209672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                index = true;
7210672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                add = true;
7211672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                wback = false;
7212672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7213672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
7214672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                shift_t = SRType_LSL;
7215672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                shift_n = 0;
7216672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7217672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                break;
7218672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7219672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            case eEncodingT2:
7220bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE PLI;
7221bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSB (literal);
7222672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7223672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                t = Bits32 (opcode, 15, 12);
7224672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                n = Bits32 (opcode, 19, 16);
7225672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                m = Bits32 (opcode, 3, 0);
7226672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7227672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
7228672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                index = true;
7229672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                add = true;
7230672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                wback = false;
7231672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7232672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7233672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                shift_t = SRType_LSL;
7234672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                shift_n = Bits32 (opcode, 5, 4);
7235672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7236672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7237672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                if ((t == 13) || BadReg (m))
7238672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                    return false;
7239672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                break;
7240672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7241672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            case eEncodingA1:
7242bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRSBT;
7243672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7244672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                t = Bits32 (opcode, 15, 12);
7245672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                n = Bits32 (opcode, 19, 16);
7246672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                m = Bits32 (opcode, 3, 0);
7247672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7248bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7249672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                index = BitIsSet (opcode, 24);
7250672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                add = BitIsSet (opcode, 23);
7251672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7252672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7253672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
7254672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                shift_t = SRType_LSL;
7255672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                shift_n = 0;
7256672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7257672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // if t == 15 || m == 15 then UNPREDICTABLE;
7258672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                if ((t == 15) || (m == 15))
7259672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                    return false;
7260672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7261672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7262672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                if (wback && ((n == 15) || (n == t)))
7263672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                    return false;
7264672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                break;
7265672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7266672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            default:
7267672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                return false;
7268672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        }
7269672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7270672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7271672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (!success)
7272672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            return false;
7273672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7274672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7275a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7276a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
7277a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
7278672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7279672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        addr_t offset_addr;
7280672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        addr_t address;
7281672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7282672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7283672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7284672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (!success)
7285672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            return false;
7286672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7287672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (add)
7288672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            offset_addr = Rn + offset;
7289672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        else
7290672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            offset_addr = Rn - offset;
7291672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7292672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        // address = if index then offset_addr else R[n];
7293672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (index)
7294672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            address = offset_addr;
7295672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        else
7296672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            address = Rn;
7297672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7298672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        // R[t] = SignExtend(MemU[address,1], 32);
7299c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
7300c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7301c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo offset_reg;
7302c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7303672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7304672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        EmulateInstruction::Context context;
7305672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        context.type = eContextRegisterLoad;
7306672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7307672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7308672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7309672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (!success)
7310672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            return false;
7311672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7312672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7313672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7314672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            return false;
7315672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
7316672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        // if wback then R[n] = offset_addr;
7317672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        if (wback)
7318672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        {
7319672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            context.type = eContextAdjustBaseRegister;
7320672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            context.SetAddress (offset_addr);
7321672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7322672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice                return false;
7323672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice        }
7324672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice    }
7325672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice    return true;
7326672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice}
7327672f3110bdd2a088f10ae9f246aaab5daa7b0fa1Caroline Tice
732878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
732978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
733078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice// pre-indexed addressing.
733178fb5638da9c01a39443f3339ede2f02056822cfCaroline Ticebool
73327bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
733378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice{
733478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#if 0
733578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice    if ConditionPassed() then
733678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
733778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
733878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        address = if index then offset_addr else R[n];
733978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        data = MemU[address,2];
734078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if wback then R[n] = offset_addr;
7341bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> = '0' then
734278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            R[t] = SignExtend(data, 32);
734378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        else // Can only apply before ARMv7
734478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            R[t] = bits(32) UNKNOWN;
734578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice#endif
734678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
734778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice    bool success = false;
734878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
73497bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
735078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice    {
735178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        uint32_t t;
735278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        uint32_t n;
735378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        uint32_t imm32;
735478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        bool index;
735578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        bool add;
735678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        bool wback;
735778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
735878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
735978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        switch (encoding)
736078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        {
736178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            case eEncodingT1:
7362bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSH (literal);
7363bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE "Unallocated memory hints";
736478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
736578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                t = Bits32 (opcode, 15, 12);
736678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                n = Bits32 (opcode, 19, 16);
736778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
736878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
736978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
737078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                index = true;
737178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                add = true;
737278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                wback = false;
737378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
737478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // if t == 13 then UNPREDICTABLE;
737578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                if (t == 13)
737678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                    return false;
737778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
737878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                break;
737978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
738078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            case eEncodingT2:
7381bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSH (literal);
7382bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7383bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7384bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '0' then UNDEFINED;
738578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
738678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                  return false;
738778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
738878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
738978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                t = Bits32 (opcode, 15, 12);
739078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                n = Bits32 (opcode, 19, 16);
739178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                imm32 = Bits32 (opcode, 7, 0);
739278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
7393bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
739478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                index = BitIsSet (opcode, 10);
739578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                add = BitIsSet (opcode, 9);
739678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                wback = BitIsSet (opcode, 8);
739778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
739878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
739978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                if (BadReg (t) || (wback && (n == t)))
740078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                    return false;
740178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
740278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                break;
740378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
740478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            case eEncodingA1:
740578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            {
7406bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSH (literal);
7407bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRSHT;
740878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
740978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                t = Bits32 (opcode, 15, 12);
741078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                n = Bits32 (opcode, 19, 16);
741178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                uint32_t imm4H = Bits32 (opcode, 11,8);
741278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                uint32_t imm4L = Bits32 (opcode, 3, 0);
741340b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice                imm32 = (imm4H << 4) | imm4L;
741478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
7415bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
741678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                index = BitIsSet (opcode, 24);
741778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                add = BitIsSet (opcode, 23);
741878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
741978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
742078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
742178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                if ((t == 15) || (wback && (n == t)))
742278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                    return false;
742378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
742478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                break;
742578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            }
742678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
742778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            default:
742878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                return false;
742978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        }
743078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
743178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
743278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
743378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if (!success)
743478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            return false;
743578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
743678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        addr_t offset_addr;
743778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if (add)
743878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            offset_addr = Rn + imm32;
743978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        else
744078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            offset_addr = Rn - imm32;
744178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
744278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        // address = if index then offset_addr else R[n];
744378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        addr_t address;
744478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if (index)
744578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            address = offset_addr;
744678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        else
744778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            address = Rn;
744878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
744978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        // data = MemU[address,2];
7450c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
7451c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
745278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
745378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        EmulateInstruction::Context context;
745478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        context.type = eContextRegisterLoad;
745578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
745678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
745778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        uint64_t data = MemURead (context, address, 2, 0, &success);
745878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if (!success)
745978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            return false;
746078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
746178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        // if wback then R[n] = offset_addr;
746278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if (wback)
746378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        {
746478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            context.type = eContextAdjustBaseRegister;
746578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            context.SetAddress (offset_addr);
746678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
746778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                return false;
746878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        }
746978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
7470bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> = '0' then
747178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        if (UnalignedSupport() || BitIsClear (address, 0))
747278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        {
747378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            // R[t] = SignExtend(data, 32);
747478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            int64_t signed_data = llvm::SignExtend64<16>(data);
747578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            context.type = eContextRegisterLoad;
747678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - Rn);
747778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
747878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice                return false;
747978fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        }
748078fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        else // Can only apply before ARMv7
748178fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        {
748278fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            // R[t] = bits(32) UNKNOWN;
748378fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice            WriteBits32Unknown (t);
748478fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice        }
748578fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice    }
748678fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice    return true;
748778fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice}
748878fb5638da9c01a39443f3339ede2f02056822cfCaroline Tice
7489d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7490d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice// sign-extends it to from a 32-bit word, and writes it to a register.
7491d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Ticebool
74927bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7493d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice{
7494d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#if 0
7495d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice    if ConditionPassed() then
7496d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7497d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        base = Align(PC,4);
7498d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        address = if add then (base + imm32) else (base - imm32);
7499d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        data = MemU[address,2];
7500bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> = '0' then
7501d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            R[t] = SignExtend(data, 32);
7502d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        else // Can only apply before ARMv7
7503d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            R[t] = bits(32) UNKNOWN;
7504d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice#endif
7505d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7506d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice    bool success = false;
7507d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
75087bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
7509d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice    {
7510d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        uint32_t t;
7511d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        uint32_t imm32;
7512d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        bool add;
7513d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7514d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7515d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        switch (encoding)
7516d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        {
7517d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            case eEncodingT1:
7518bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE "Unallocated memory hints";
7519bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7520d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                t = Bits32  (opcode, 15, 12);
7521d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
7522d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                add = BitIsSet (opcode, 23);
7523d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7524d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                // if t == 13 then UNPREDICTABLE;
7525d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                if (t == 13)
7526d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                    return false;
7527d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7528d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                break;
7529d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7530d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            case eEncodingA1:
7531d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            {
7532bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7533d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                t = Bits32 (opcode, 15, 12);
7534d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                uint32_t imm4H = Bits32 (opcode, 11, 8);
7535d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                uint32_t imm4L = Bits32 (opcode, 3, 0);
753640b1a6cd1190d820b630395f08c06d47e0bf6c7dCaroline Tice                imm32 = (imm4H << 4) | imm4L;
7537d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                add = BitIsSet (opcode, 23);
7538d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7539d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                // if t == 15 then UNPREDICTABLE;
7540d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                if (t == 15)
7541d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                    return false;
7542d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7543d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                break;
7544d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            }
7545d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            default:
7546d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                return false;
7547d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        }
7548d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7549d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        // base = Align(PC,4);
75508d681f52cd597b0148c9ae1439d5d5877aa39e4dCaroline Tice        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7551d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        if (!success)
7552d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            return false;
7553d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7554d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        uint64_t base = AlignPC (pc_value);
7555d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7556d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        addr_t address;
7557d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        // address = if add then (base + imm32) else (base - imm32);
7558d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        if (add)
7559d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            address = base + imm32;
7560d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        else
7561d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            address = base - imm32;
7562d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7563d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        // data = MemU[address,2];
7564c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
7565c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7566d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7567d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        EmulateInstruction::Context context;
7568d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        context.type = eContextRegisterLoad;
7569d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        context.SetRegisterPlusOffset (base_reg, imm32);
7570d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7571d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        uint64_t data = MemURead (context, address, 2, 0, &success);
7572d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        if (!success)
7573d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            return false;
7574d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7575bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> = '0' then
7576d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        if (UnalignedSupport() || BitIsClear (address, 0))
7577d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        {
7578d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            // R[t] = SignExtend(data, 32);
7579d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            int64_t signed_data = llvm::SignExtend64<16>(data);
7580d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7581d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice                return false;
7582d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        }
7583d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        else // Can only apply before ARMv7
7584d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        {
7585d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            // R[t] = bits(32) UNKNOWN;
7586d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice            WriteBits32Unknown (t);
7587d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice        }
7588d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice    }
7589d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice    return true;
7590d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice}
7591d2fac095321ccd262699a8cce8b9fc897d6dff0dCaroline Tice
7592291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7593291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7594291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice// shifted left by 0, 1, 2, or 3 bits.
7595291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Ticebool
75967bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7597291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice{
7598291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#if 0
7599291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice    if ConditionPassed() then
7600291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7601291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7602291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7603291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        address = if index then offset_addr else R[n];
7604291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        data = MemU[address,2];
7605291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if wback then R[n] = offset_addr;
7606bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        if UnalignedSupport() || address<0> = '0' then
7607291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            R[t] = SignExtend(data, 32);
7608291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        else // Can only apply before ARMv7
7609291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            R[t] = bits(32) UNKNOWN;
7610291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice#endif
7611291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7612291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice    bool success = false;
7613291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
76147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
7615291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice    {
7616291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint32_t t;
7617291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint32_t n;
7618291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint32_t m;
7619291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        bool index;
7620291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        bool add;
7621291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        bool wback;
7622291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        ARM_ShifterType shift_t;
7623291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint32_t shift_n;
7624291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7625291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7626291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        switch (encoding)
7627291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        {
7628291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            case eEncodingT1:
7629291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7630291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7631291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                t = Bits32 (opcode, 2, 0);
7632291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                n = Bits32 (opcode, 5, 3);
7633291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                m = Bits32 (opcode, 8, 6);
7634291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7635291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
7636291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                index = true;
7637291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                add = true;
7638291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                wback = false;
7639291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7640291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
7641291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                shift_t = SRType_LSL;
7642291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                shift_n = 0;
7643291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7644291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                break;
7645291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7646291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            case eEncodingT2:
7647bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rn == '1111' then SEE LDRSH (literal);
7648bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if Rt == '1111' then SEE "Unallocated memory hints";
7649291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7650291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                t = Bits32 (opcode, 15, 12);
7651291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                n = Bits32 (opcode, 19, 16);
7652291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                m = Bits32 (opcode, 3, 0);
7653291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7654291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // index = TRUE; add = TRUE; wback = FALSE;
7655291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                index = true;
7656291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                add = true;
7657291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                wback = false;
7658291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7659291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7660291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                shift_t = SRType_LSL;
7661291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                shift_n = Bits32 (opcode, 5, 4);
7662291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7663291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7664291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                if ((t == 13) || BadReg (m))
7665291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                    return false;
7666291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7667291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                break;
7668291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7669291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            case eEncodingA1:
7670bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // if P == '0' && W == '1' then SEE LDRSHT;
7671291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7672291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                t = Bits32 (opcode, 15, 12);
7673291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                n = Bits32 (opcode, 19, 16);
7674291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                m = Bits32 (opcode, 3, 0);
7675291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7676bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7677291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                index = BitIsSet (opcode, 24);
7678291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                add = BitIsSet (opcode, 23);
7679291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7680291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7681291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
7682291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                shift_t = SRType_LSL;
7683291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                shift_n = 0;
7684291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7685291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // if t == 15 || m == 15 then UNPREDICTABLE;
7686291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                if ((t == 15) || (m == 15))
7687291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                    return false;
7688291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7689291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7690291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                if (wback && ((n == 15) || (n == t)))
7691291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                    return false;
7692291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7693291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                break;
7694291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7695291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            default:
76966ac9e54dfd1d3e4be4326e0f1740e6a5971c4759Johnny Chen                return false;
7697291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        }
7698291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7699291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7700291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (!success)
7701291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            return false;
7702291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7703291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7704291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (!success)
7705291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            return false;
7706291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7707291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7708a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7709a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
7710a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
7711291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7712291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        addr_t offset_addr;
7713291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        addr_t address;
7714291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7715291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7716291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (add)
7717291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            offset_addr = Rn + offset;
7718291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        else
7719291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            offset_addr = Rn - offset;
7720291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7721291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        // address = if index then offset_addr else R[n];
7722291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (index)
7723291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            address = offset_addr;
7724291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        else
7725291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            address = Rn;
7726291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7727291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        // data = MemU[address,2];
7728c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
7729c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7730291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7731c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo offset_reg;
7732c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7733291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7734291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        EmulateInstruction::Context context;
7735291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        context.type = eContextRegisterLoad;
7736291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7737291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7738291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        uint64_t data = MemURead (context, address, 2, 0, &success);
7739291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (!success)
7740291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            return false;
7741291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7742291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        // if wback then R[n] = offset_addr;
7743291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (wback)
7744291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        {
7745291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            context.type = eContextAdjustBaseRegister;
7746291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            context.SetAddress (offset_addr);
7747291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7748291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                return false;
7749291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        }
7750291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7751bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if UnalignedSupport() || address<0> = '0' then
7752291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        if (UnalignedSupport() || BitIsClear (address, 0))
7753291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        {
7754291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            // R[t] = SignExtend(data, 32);
7755291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            context.type = eContextRegisterLoad;
7756291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7757291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7758291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            int64_t signed_data = llvm::SignExtend64<16>(data);
7759291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7760291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice                return false;
7761291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        }
7762291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        else // Can only apply before ARMv7
7763291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        {
7764291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            // R[t] = bits(32) UNKNOWN;
7765291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice            WriteBits32Unknown (t);
7766291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice        }
7767291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice    }
7768291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice    return true;
7769291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice}
77706bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
77716bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
77726bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
77736bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Ticebool
77747bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
77756bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice{
77766bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#if 0
77776bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice    if ConditionPassed() then
77786bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        EncodingSpecificOperations();
77796bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        rotated = ROR(R[m], rotation);
77806bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        R[d] = SignExtend(rotated<7:0>, 32);
77816bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice#endif
77826bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
77836bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice    bool success = false;
77846bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
77857bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
77866bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice    {
77876bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        uint32_t d;
77886bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        uint32_t m;
77896bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        uint32_t rotation;
77906bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
77916bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        // EncodingSpecificOperations();
77926bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        switch (encoding)
77936bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        {
77946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice            case eEncodingT1:
77956bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
77966bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                d = Bits32 (opcode, 2, 0);
77976bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                m = Bits32 (opcode, 5, 3);
77986bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                rotation = 0;
77996bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78006bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                break;
78016bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78026bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice            case eEncodingT2:
7803bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
78046bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                d = Bits32 (opcode, 11, 8);
78056bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                m = Bits32 (opcode, 3, 0);
78066bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                rotation = Bits32 (opcode, 5, 4) << 3;
78076bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78086bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
78096bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                if (BadReg (d) || BadReg (m))
78106bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                    return false;
78116bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78126bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                break;
78136bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78146bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice            case eEncodingA1:
7815bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
78166bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                d = Bits32 (opcode, 15, 12);
78176bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                m = Bits32 (opcode, 3, 0);
78186bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                rotation = Bits32 (opcode, 11, 10) << 3;
78196bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78206bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                // if d == 15 || m == 15 then UNPREDICTABLE;
78216bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                if ((d == 15) || (m == 15))
78226bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                    return false;
78236bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78246bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                break;
78256bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78266bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice            default:
78276bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice                return false;
78286bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        }
78296bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
7830868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7831868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        if (!success)
7832868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            return false;
78336bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78346bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        // rotated = ROR(R[m], rotation);
7835a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint64_t rotated = ROR (Rm, rotation, &success);
7836a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
7837a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
78386bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78396bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        // R[d] = SignExtend(rotated<7:0>, 32);
78408ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        int64_t data = llvm::SignExtend64<8>(rotated);
78416bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
7842c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo source_reg;
7843c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
78446bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78456bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        EmulateInstruction::Context context;
78466bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        context.type = eContextRegisterLoad;
78476bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        context.SetRegister (source_reg);
78486bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
78498ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
78506bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice            return false;
78516bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice    }
78526bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice    return true;
78536bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice}
7854291a3e90e7a275f196bc7aeeb2137acd6d60229fCaroline Tice
7855868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7856868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7857868198b229fcffbda2b24518007179ef1a45ad1dCaroline Ticebool
78587bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7859868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice{
7860868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#if 0
7861868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice    if ConditionPassed() then
7862868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        EncodingSpecificOperations();
7863868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        rotated = ROR(R[m], rotation);
7864868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        R[d] = SignExtend(rotated<15:0>, 32);
7865868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice#endif
7866868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7867868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice    bool success = false;
7868868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
78697bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
7870868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice    {
7871868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        uint32_t d;
7872868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        uint32_t m;
7873868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        uint32_t rotation;
7874868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7875868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        // EncodingSpecificOperations();
7876868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        switch (encoding)
7877868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        {
7878868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            case eEncodingT1:
7879868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7880868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                d = Bits32 (opcode, 2, 0);
7881868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                m = Bits32 (opcode, 5, 3);
7882868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                rotation = 0;
7883868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7884868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                break;
7885868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7886868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            case eEncodingT2:
7887bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7888868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                d = Bits32 (opcode, 11, 8);
7889868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                m = Bits32 (opcode, 3, 0);
7890868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                rotation = Bits32 (opcode, 5, 4) << 3;
7891868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7892868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7893868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                if (BadReg (d) || BadReg (m))
7894868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                    return false;
7895868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7896868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                break;
7897868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7898868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            case eEncodingA1:
7899bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7900868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                d = Bits32 (opcode, 15, 12);
7901868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                m = Bits32 (opcode, 3, 0);
7902868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                rotation = Bits32 (opcode, 11, 10) << 3;
7903868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7904868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                // if d == 15 || m == 15 then UNPREDICTABLE;
7905868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                if ((d == 15) || (m == 15))
7906868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                    return false;
7907868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7908868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                break;
7909868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7910868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            default:
7911868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice                return false;
7912868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        }
7913868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7914868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7915868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        if (!success)
7916868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            return false;
7917868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7918868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        // rotated = ROR(R[m], rotation);
7919a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint64_t rotated = ROR (Rm, rotation, &success);
7920a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
7921a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
7922868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7923868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        // R[d] = SignExtend(rotated<15:0>, 32);
7924c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo source_reg;
7925c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7926868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7927868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        EmulateInstruction::Context context;
7928868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        context.type = eContextRegisterLoad;
7929868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice        context.SetRegister (source_reg);
7930868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
79318ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        int64_t data = llvm::SignExtend64<16> (rotated);
79328ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7933868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice            return false;
7934868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice    }
7935868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
7936868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice    return true;
7937868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice}
7938868198b229fcffbda2b24518007179ef1a45ad1dCaroline Tice
79398ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
79408ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
79418ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Ticebool
79427bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
79438ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice{
79448ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#if 0
79458ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice    if ConditionPassed() then
79468ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        EncodingSpecificOperations();
79478ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        rotated = ROR(R[m], rotation);
79488ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        R[d] = ZeroExtend(rotated<7:0>, 32);
79498ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice#endif
79508ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79518ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice    bool success = false;
79528ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79537bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
79548ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice    {
79558ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        uint32_t d;
79568ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        uint32_t m;
79578ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        uint32_t rotation;
79588ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79598ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        // EncodingSpecificOperations();
79608ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        switch (encoding)
79618ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        {
79628ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice            case eEncodingT1:
79638ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
79648ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                d = Bits32 (opcode, 2, 0);
79658ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                m = Bits32 (opcode, 5, 3);
79668ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                rotation = 0;
79678ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79688ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                break;
79698ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79708ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice            case eEncodingT2:
7971bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
79728ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                d = Bits32 (opcode, 11, 8);
79738ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                m = Bits32 (opcode, 3, 0);
79748ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                  rotation = Bits32 (opcode, 5, 4) << 3;
79758ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79768ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
79778ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                if (BadReg (d) || BadReg (m))
79788ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                  return false;
79798ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79808ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                break;
79818ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79828ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice            case eEncodingA1:
7983bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
79848ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                d = Bits32 (opcode, 15, 12);
79858ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                m = Bits32 (opcode, 3, 0);
79868ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                rotation = Bits32 (opcode, 11, 10) << 3;
79878ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79888ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                // if d == 15 || m == 15 then UNPREDICTABLE;
79898ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                if ((d == 15) || (m == 15))
79908ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                    return false;
79918ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79928ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                break;
79938ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79948ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice            default:
79958ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice                return false;
79968ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        }
79978ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
79988ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
79998ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        if (!success)
80008ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice            return false;
80018ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
80028ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        // rotated = ROR(R[m], rotation);
8003a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint64_t rotated = ROR (Rm, rotation, &success);
8004a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
8005a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
80068ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
80078ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        // R[d] = ZeroExtend(rotated<7:0>, 32);
8008c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo source_reg;
8009c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
80108ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
80118ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        EmulateInstruction::Context context;
80128ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        context.type = eContextRegisterLoad;
80138ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        context.SetRegister (source_reg);
80148ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
80158ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
80168ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice            return false;
80178ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice    }
80188ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice    return true;
80198ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice}
80208ce96d910ba57058e10a563bcaab4448ca9ad571Caroline Tice
802111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
802211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
802311555f2f0f21beb0312f8ebe40849487d437f493Caroline Ticebool
80247bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
802511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice{
802611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#if 0
802711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice    if ConditionPassed() then
802811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        EncodingSpecificOperations();
802911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        rotated = ROR(R[m], rotation);
803011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        R[d] = ZeroExtend(rotated<15:0>, 32);
803111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice#endif
803211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
803311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice    bool success = false;
803411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
80357bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
803611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice    {
803711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        uint32_t d;
803811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        uint32_t m;
803911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        uint32_t rotation;
804011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
804111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        switch (encoding)
804211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        {
804311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice            case eEncodingT1:
804411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
804511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                d = Bits32 (opcode, 2, 0);
804611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                m = Bits32 (opcode, 5, 3);
804711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                rotation = 0;
804811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
804911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                break;
805011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
805111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice            case eEncodingT2:
8052bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
805311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                d = Bits32 (opcode, 11, 8);
805411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                m = Bits32 (opcode, 3, 0);
805511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                rotation = Bits32 (opcode, 5, 4) << 3;
805611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
805711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
805811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                if (BadReg (d) || BadReg (m))
805911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                  return false;
806011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
806111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                break;
806211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
806311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice            case eEncodingA1:
8064bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
806511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                d = Bits32 (opcode, 15, 12);
806611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                m = Bits32 (opcode, 3, 0);
806711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                rotation = Bits32 (opcode, 11, 10) << 3;
806811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
806911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                // if d == 15 || m == 15 then UNPREDICTABLE;
807011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                if ((d == 15) || (m == 15))
807111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                    return false;
807211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
807311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                break;
807411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
807511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice            default:
807611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice                return false;
807711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        }
807811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
807911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
808011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        if (!success)
808111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice            return false;
808211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
808311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        // rotated = ROR(R[m], rotation);
8084a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint64_t rotated = ROR (Rm, rotation, &success);
8085a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
8086a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
808711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
808811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        // R[d] = ZeroExtend(rotated<15:0>, 32);
8089c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo source_reg;
8090c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
809111555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
809211555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        EmulateInstruction::Context context;
809311555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        context.type = eContextRegisterLoad;
809411555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        context.SetRegister (source_reg);
809511555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
809611555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
809711555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice            return false;
809811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice    }
809911555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice    return true;
810011555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice}
8101b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8102b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8103b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice// word respectively.
8104b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool
81057bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8106b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{
8107b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#if 0
8108b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if ConditionPassed() then
8109b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        EncodingSpecificOperations();
8110b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8111b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            UNPREDICTABLE;
8112b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        else
8113b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            address = if increment then R[n] else R[n]-8;
8114b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if wordhigher then address = address+4;
8115bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8116b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            BranchWritePC(MemA[address,4]);
8117b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8118b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice#endif
8119b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8120b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    bool success = false;
8121b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
81227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
8123b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    {
8124b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        uint32_t n;
8125b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        bool wback;
8126b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        bool increment;
8127b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        bool wordhigher;
8128b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8129b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        // EncodingSpecificOperations();
8130b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        switch (encoding)
8131b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        {
8132b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            case eEncodingT1:
8133bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8134b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                n = Bits32 (opcode, 19, 16);
8135b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                wback = BitIsSet (opcode, 21);
8136b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                increment = false;
8137b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                wordhigher = false;
8138b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8139b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                // if n == 15 then UNPREDICTABLE;
8140b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                if (n == 15)
8141b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    return false;
8142b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8143b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8144b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                if (InITBlock() && !LastInITBlock())
8145b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    return false;
8146b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8147b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                break;
8148b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8149b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            case eEncodingT2:
8150bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8151b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                n = Bits32 (opcode, 19, 16);
8152b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                wback = BitIsSet (opcode, 21);
8153b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                increment = true;
8154b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                wordhigher = false;
8155b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8156b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                // if n == 15 then UNPREDICTABLE;
8157b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                if (n == 15)
8158b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    return false;
8159b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8160b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8161b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                if (InITBlock() && !LastInITBlock())
8162b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    return false;
8163b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8164b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                break;
8165b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8166b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            case eEncodingA1:
8167b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                // n = UInt(Rn);
8168b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                n = Bits32 (opcode, 19, 16);
8169b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8170bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8171b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                wback = BitIsSet (opcode, 21);
8172b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                increment = BitIsSet (opcode, 23);
8173b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8174b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8175b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                // if n == 15 then UNPREDICTABLE;
8176b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                if (n == 15)
8177b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    return false;
8178b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8179b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                break;
8180b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8181b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            default:
8182b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                return false;
8183b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        }
8184b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8185b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8186b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (!CurrentModeIsPrivileged ())
8187b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            // UNPREDICTABLE;
8188b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            return false;
8189b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        else
8190b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        {
8191b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8192b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if (!success)
8193b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                return false;
8194b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8195b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            addr_t address;
8196b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            // address = if increment then R[n] else R[n]-8;
8197b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if (increment)
8198b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                address = Rn;
8199b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            else
8200b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                address = Rn - 8;
8201b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8202b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            // if wordhigher then address = address+4;
8203b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if (wordhigher)
8204b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                address = address + 4;
8205b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8206bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8207c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            RegisterInfo base_reg;
8208c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8209b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8210b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            EmulateInstruction::Context context;
8211b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            context.type = eContextReturnFromException;
8212b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            context.SetRegisterPlusOffset (base_reg, address - Rn);
8213b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8214b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8215b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if (!success)
8216b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                return false;
8217b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8218b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            CPSRWriteByInstr (data, 15, true);
8219b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8220b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            // BranchWritePC(MemA[address,4]);
8221b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8222b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if (!success)
8223b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                return false;
8224b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8225b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            BranchWritePC (context, data2);
8226b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
8227b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8228b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            if (wback)
8229b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            {
8230b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                context.type = eContextAdjustBaseRegister;
8231b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                if (increment)
8232b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                {
8233b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    context.SetOffset (8);
8234b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8235b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                        return false;
8236b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                }
8237b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                else
8238b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                {
8239b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    context.SetOffset (-8);
8240b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8241b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                        return false;
8242b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice                }
8243b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            } // if wback
8244b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        }
8245b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    } // if ConditionPassed()
8246b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    return true;
8247b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice}
824811555f2f0f21beb0312f8ebe40849487d437f493Caroline Tice
82492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
82502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// and writes the result to the destination register.  It can optionally update the condition flags based on
82512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result.
82522115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
82537bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
82542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
82552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
82562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
82572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
82582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
82592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR imm32;
82602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
82612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
82622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        else
82632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            R[d] = result;
82642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if setflags then
82652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.N = result<31>;
82662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.Z = IsZeroBit(result);
82672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.C = carry;
82682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                // APSR.V unchanged
82692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
82702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
82712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
82722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
82737bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
82742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
82752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rd, Rn;
82762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
82772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        bool setflags;
82782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
82792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
82802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
82812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
82822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 11, 8);
82832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
82842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
82852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
82862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
82872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
82887bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateTEQImm (opcode, eEncodingT1);
82892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
82902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
82912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
82922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
82932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 15, 12);
82942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
82952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
82962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
82971f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
82982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
82992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
83001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
83012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
83022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
83032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
83042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
83052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
83072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
83082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
83092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
83102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ imm32;
83122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
83142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
83152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
83162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
83182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
83192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
83202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
83212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
83222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
83242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value, and writes the result to the destination register.
83252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// It can optionally update the condition flags based on the result.
83262115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
83277bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
83282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
83292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
83302115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
83312115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
83322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
83332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
83342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR shifted;
83352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if d == 15 then         // Can only occur for ARM encoding
83362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            ALUWritePC(result); // setflags is always FALSE here
83372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        else
83382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            R[d] = result;
83392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if setflags then
83402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.N = result<31>;
83412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.Z = IsZeroBit(result);
83422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                APSR.C = carry;
83432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                // APSR.V unchanged
83442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
83452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
83472115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83487bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
83492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
83502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rd, Rn, Rm;
83512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        ARM_ShifterType shift_t;
83522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
83532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        bool setflags;
83542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry;
83552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
83562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
83572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
83582115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
83592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 5, 3);
83602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = !InITBlock();
83612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_t = SRType_LSL;
83622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            shift_n = 0;
8363ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
83642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT2:
83652115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 11, 8);
83662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
83672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
83682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
83693dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
83703dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            // if Rd == '1111' && S == '1' then SEE TEQ (register);
83712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
83727bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateTEQReg (opcode, eEncodingT1);
83732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
83742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
83752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
83762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
83772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rd = Bits32(opcode, 15, 12);
83782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
83792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
83802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            setflags = BitIsSet(opcode, 20);
83813dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
83821f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
83832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
83842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (Rd == 15 && setflags)
83851f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
83862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
83872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
83882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
83892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
83902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
83922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
83932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
83942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
83952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
83962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the second operand.
83972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
83982115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
83992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
84002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
8401a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8402a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
8403a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
84042115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ shifted;
84052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
84062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
84072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
84082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
84092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
84102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
84112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
84122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
84132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
84142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
84152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
84167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
84177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// writes the result to the destination register.  It can optionally update the condition flags based
84187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result.
84197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool
84207bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
84217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{
84227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0
84237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    // ARM pseudo code...
84247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if ConditionPassed() then
84257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EncodingSpecificOperations();
84267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        result = R[n] OR imm32;
84277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
84287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
84297c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        else
84307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            R[d] = result;
84317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if setflags then
84327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.N = result<31>;
84337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.Z = IsZeroBit(result);
84347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.C = carry;
84357c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                // APSR.V unchanged
84367c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif
84377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84387c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    bool success = false;
84397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84407bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
84417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    {
84427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t Rd, Rn;
84437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
84447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        bool setflags;
84457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
84467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        switch (encoding)
84477c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        {
84487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT1:
84497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
84507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
84517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
84527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8453bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice            // if Rn == '1111' then SEE MOV (immediate);
84547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rn == 15)
84557bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateMOVRdImm (opcode, eEncodingT2);
84567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (BadReg(Rd) || Rn == 13)
84577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
84587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
84597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingA1:
84607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 15, 12);
84617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
84627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
84637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
84641f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
84657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rd == 15 && setflags)
84661f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
84677c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
84687c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        default:
84697c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
84707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        }
84717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // Read the first operand.
84737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
84747c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!success)
84757c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
84767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t result = val1 | imm32;
84787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EmulateInstruction::Context context;
84807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
84817c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.SetNoArgs ();
84827c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84837c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
84847c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
84857c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    }
84867c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    return true;
84877c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen}
84887c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
84897c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
84907c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// value, and writes the result to the destination register.  It can optionally update the condition flags based
84917c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen// on the result.
84927c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chenbool
84937bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
84947c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen{
84957c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#if 0
84967c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    // ARM pseudo code...
84977c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    if ConditionPassed() then
84987c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EncodingSpecificOperations();
84997c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
85007c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        result = R[n] OR shifted;
85017c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
85027c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
85037c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        else
85047c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            R[d] = result;
85057c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if setflags then
85067c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.N = result<31>;
85077c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.Z = IsZeroBit(result);
85087c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                APSR.C = carry;
85097c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                // APSR.V unchanged
85107c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen#endif
85117c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
85127c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    bool success = false;
85137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
85147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
85157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    {
85167c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t Rd, Rn, Rm;
85177c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        ARM_ShifterType shift_t;
85187c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
85197c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        bool setflags;
85207c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t carry;
85217c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        switch (encoding)
85227c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        {
85237c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT1:
85247c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Rn = Bits32(opcode, 2, 0);
85257c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 5, 3);
85267c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = !InITBlock();
85277c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            shift_t = SRType_LSL;
85287c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            shift_n = 0;
8529ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
85307c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingT2:
85317c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 11, 8);
85327c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
85337c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 3, 0);
85347c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
85353dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
85363dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            // if Rn == '1111' then SEE MOV (register);
85377c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rn == 15)
85387bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                return EmulateMOVRdRm (opcode, eEncodingT3);
85397c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
85407c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen                return false;
85417c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
85427c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        case eEncodingA1:
85437c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rd = Bits32(opcode, 15, 12);
85447c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rn = Bits32(opcode, 19, 16);
85457c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            Rm = Bits32(opcode, 3, 0);
85467c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            setflags = BitIsSet(opcode, 20);
85473dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
85481f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
85497c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            if (Rd == 15 && setflags)
85501f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return EmulateSUBSPcLrEtc (opcode, encoding);
85517c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            break;
85527c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        default:
85537c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
85547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        }
85557c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
85567c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // Read the first operand.
85577c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
85587c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!success)
85597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
85607c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
85617c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // Read the second operand.
85627c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
85637c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!success)
85647c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
85657c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
8566a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8567a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
8568a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
85692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 | shifted;
85707c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
85717c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        EmulateInstruction::Context context;
85727c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
85737c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        context.SetNoArgs ();
85747c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
85757c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
85767c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen            return false;
85777c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    }
85787c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen    return true;
85797c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen}
85807c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
8581ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8582ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// the destination register. It can optionally update the condition flags based on the result.
8583ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool
85847bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8585ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{
8586ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0
8587ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    // ARM pseudo code...
8588ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if ConditionPassed() then
8589ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        EncodingSpecificOperations();
8590ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8591ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
8592ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
8593ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        else
8594ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            R[d] = result;
8595ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            if setflags then
8596ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.N = result<31>;
8597ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.Z = IsZeroBit(result);
8598ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.C = carry;
8599ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.V = overflow;
8600ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif
8601ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8602ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    bool success = false;
8603ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8604ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t Rd; // the destination register
8605ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t Rn; // the first operand
8606ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    bool setflags;
8607ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8608ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    switch (encoding) {
8609ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    case eEncodingT1:
8610ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rd = Bits32(opcode, 2, 0);
8611ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rn = Bits32(opcode, 5, 3);
8612ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        setflags = !InITBlock();
8613ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        imm32 = 0;
8614ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
8615ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    case eEncodingT2:
8616ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rd = Bits32(opcode, 11, 8);
8617ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rn = Bits32(opcode, 19, 16);
8618ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        setflags = BitIsSet(opcode, 20);
8619ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8620ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        if (BadReg(Rd) || BadReg(Rn))
8621ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            return false;
8622ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
8623ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    case eEncodingA1:
8624ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rd = Bits32(opcode, 15, 12);
8625ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rn = Bits32(opcode, 19, 16);
8626ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        setflags = BitIsSet(opcode, 20);
8627ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
86281f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
8629ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8630ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        if (Rd == 15 && setflags)
86311f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc (opcode, encoding);
8632ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
8633ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    default:
8634ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8635ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    }
8636ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    // Read the register value from the operand register Rn.
8637ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
8638ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if (!success)
8639ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8640ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8641ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8642ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8643ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    EmulateInstruction::Context context;
8644ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
8645ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    context.SetNoArgs ();
8646ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8647ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8648ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8649ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8650ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    return true;
8651ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen}
8652ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8653ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8654ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen// result to the destination register. It can optionally update the condition flags based on the result.
8655ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chenbool
86567bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8657ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen{
8658ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#if 0
8659ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    // ARM pseudo code...
8660ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if ConditionPassed() then
8661ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        EncodingSpecificOperations();
8662ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8663ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8664ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
8665ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
8666ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        else
8667ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            R[d] = result;
8668ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            if setflags then
8669ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.N = result<31>;
8670ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.Z = IsZeroBit(result);
8671ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.C = carry;
8672ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen                APSR.V = overflow;
8673ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen#endif
8674ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8675ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    bool success = false;
8676ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8677ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t Rd; // the destination register
8678ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t Rn; // the first operand
8679ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t Rm; // the second operand
8680ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    bool setflags;
8681ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    ARM_ShifterType shift_t;
8682ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
8683ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    switch (encoding) {
8684ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    case eEncodingT1:
8685ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rd = Bits32(opcode, 11, 8);
8686ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rn = Bits32(opcode, 19, 16);
8687ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rm = Bits32(opcode, 3, 0);
8688ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        setflags = BitIsSet(opcode, 20);
8689ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8690ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8691ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8692ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            return false;
8693ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
8694ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    case eEncodingA1:
8695ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rd = Bits32(opcode, 15, 12);
8696ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rn = Bits32(opcode, 19, 16);
8697ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        Rm = Bits32(opcode, 3, 0);
8698ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        setflags = BitIsSet(opcode, 20);
8699ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        shift_n = DecodeImmShiftARM(opcode, shift_t);
87001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
8701ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8702ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        if (Rd == 15 && setflags)
87031f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc (opcode, encoding);
8704ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        break;
8705ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    default:
8706ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8707ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    }
8708ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    // Read the register value from register Rn.
8709ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
8710ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if (!success)
8711ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8712ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8713ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    // Read the register value from register Rm.
8714ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
8715ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if (!success)
8716ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8717ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8718a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8719a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    if (!success)
8720a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        return false;
8721ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8722ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8723ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    EmulateInstruction::Context context;
8724ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
8725ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    context.SetNoArgs();
8726ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8727ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        return false;
8728ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
8729ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen    return true;
8730ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen}
8731ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen
873290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
873390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// an immediate value, and writes the result to the destination register. It can optionally update the condition
873490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// flags based on the result.
873590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool
87367bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
873790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{
873890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0
873990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    // ARM pseudo code...
874090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if ConditionPassed() then
874190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        EncodingSpecificOperations();
874290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
874390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        if d == 15 then
874490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
874590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        else
874690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen            R[d] = result;
874790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen            if setflags then
874890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.N = result<31>;
874990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.Z = IsZeroBit(result);
875090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.C = carry;
875190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.V = overflow;
875290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif
875390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
875490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    bool success = false;
875590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
875690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t Rd; // the destination register
875790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t Rn; // the first operand
875890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    bool setflags;
875990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
876090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    switch (encoding) {
876190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    case eEncodingA1:
876290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        Rd = Bits32(opcode, 15, 12);
876390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        Rn = Bits32(opcode, 19, 16);
876490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        setflags = BitIsSet(opcode, 20);
876590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
87661f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
876790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
876890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        if (Rd == 15 && setflags)
87691f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc  (opcode, encoding);
877090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        break;
877190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    default:
877290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
877390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    }
877490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    // Read the register value from the operand register Rn.
877590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
877690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if (!success)
877790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
877890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
877990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
878090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
878190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    EmulateInstruction::Context context;
878290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
878390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    context.SetNoArgs ();
878490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
878590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
878690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
878790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
878890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    return true;
878990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen}
879090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
879190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
879290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
879390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen// condition flags based on the result.
879490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chenbool
87957bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
879690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen{
879790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#if 0
879890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    // ARM pseudo code...
879990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if ConditionPassed() then
880090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        EncodingSpecificOperations();
880190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
880290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
880390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        if d == 15 then
880490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
880590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        else
880690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen            R[d] = result;
880790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen            if setflags then
880890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.N = result<31>;
880990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.Z = IsZeroBit(result);
881090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.C = carry;
881190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen                APSR.V = overflow;
881290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen#endif
881390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
881490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    bool success = false;
881590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
881690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t Rd; // the destination register
881790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t Rn; // the first operand
881890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t Rm; // the second operand
881990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    bool setflags;
882090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    ARM_ShifterType shift_t;
882190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
882290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    switch (encoding) {
882390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    case eEncodingA1:
882490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        Rd = Bits32(opcode, 15, 12);
882590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        Rn = Bits32(opcode, 19, 16);
882690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        Rm = Bits32(opcode, 3, 0);
882790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        setflags = BitIsSet(opcode, 20);
882890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        shift_n = DecodeImmShiftARM(opcode, shift_t);
88291f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
883090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
883190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        if (Rd == 15 && setflags)
88321f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc (opcode, encoding);
883390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        break;
883490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    default:
883590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
883690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    }
883790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    // Read the register value from register Rn.
883890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
883990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if (!success)
884090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
884190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
884290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    // Read the register value from register Rm.
884390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
884490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if (!success)
884590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
884690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
8847a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8848a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    if (!success)
8849a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        return false;
885090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
885190e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
885290e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    EmulateInstruction::Context context;
885390e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
885490e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    context.SetNoArgs();
885590e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
885690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        return false;
885790e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
885890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen    return true;
885990e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen}
886090e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen
88619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (immediate) subtracts an immediate value and the value of
88629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register.
88639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result.
88649b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool
88657bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
88669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{
88679b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0
88689b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    // ARM pseudo code...
88699b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if ConditionPassed() then
88709b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        EncodingSpecificOperations();
887115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
88729b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
88739b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
88749b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        else
88759b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            R[d] = result;
88769b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            if setflags then
88779b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.N = result<31>;
88789b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.Z = IsZeroBit(result);
88799b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.C = carry;
88809b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.V = overflow;
88819b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif
88829b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
88839b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    bool success = false;
88849b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
88859b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t Rd; // the destination register
88869b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t Rn; // the first operand
88879b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    bool setflags;
88889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
88899b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    switch (encoding) {
88909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    case eEncodingT1:
88919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rd = Bits32(opcode, 11, 8);
88929b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rn = Bits32(opcode, 19, 16);
88939b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        setflags = BitIsSet(opcode, 20);
88949b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
88959b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        if (BadReg(Rd) || BadReg(Rn))
88969b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            return false;
88979b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        break;
88989b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    case eEncodingA1:
88999b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rd = Bits32(opcode, 15, 12);
89009b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rn = Bits32(opcode, 19, 16);
89019b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        setflags = BitIsSet(opcode, 20);
89029b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
89031f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
89049b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
89059b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        if (Rd == 15 && setflags)
89061f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc (opcode, encoding);
89079b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        break;
89089b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    default:
89099b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
89109b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    }
89119b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    // Read the register value from the operand register Rn.
89129b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
89139b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if (!success)
89149b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
89159b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89169b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
89179b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89189b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    EmulateInstruction::Context context;
89199b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
89209b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    context.SetNoArgs ();
89219b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89229b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
89239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
89249b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89259b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    return true;
89269b381775c532270fd07a90aa1a98750546a768b7Johnny Chen}
89279b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89289b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
89299b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// NOT (Carry flag) from a register value, and writes the result to the destination register.
89309b381775c532270fd07a90aa1a98750546a768b7Johnny Chen// It can optionally update the condition flags based on the result.
89319b381775c532270fd07a90aa1a98750546a768b7Johnny Chenbool
89327bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
89339b381775c532270fd07a90aa1a98750546a768b7Johnny Chen{
89349b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#if 0
89359b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    // ARM pseudo code...
89369b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if ConditionPassed() then
89379b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        EncodingSpecificOperations();
89389b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
89399b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
89409b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        if d == 15 then         // Can only occur for ARM encoding
89419b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
89429b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        else
89439b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            R[d] = result;
89449b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            if setflags then
89459b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.N = result<31>;
89469b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.Z = IsZeroBit(result);
89479b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.C = carry;
89489b381775c532270fd07a90aa1a98750546a768b7Johnny Chen                APSR.V = overflow;
89499b381775c532270fd07a90aa1a98750546a768b7Johnny Chen#endif
89509b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89519b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    bool success = false;
89529b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89539b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t Rd; // the destination register
89549b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t Rn; // the first operand
89559b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t Rm; // the second operand
89569b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    bool setflags;
89579b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    ARM_ShifterType shift_t;
89589b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t shift_n; // the shift applied to the value read from Rm
89599b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    switch (encoding) {
89609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    case eEncodingT1:
89619b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rd = Rn = Bits32(opcode, 2, 0);
89629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rm = Bits32(opcode, 5, 3);
89639b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        setflags = !InITBlock();
89649b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        shift_t = SRType_LSL;
89659b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        shift_n = 0;
89669b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        break;
89679b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    case eEncodingT2:
89689b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rd = Bits32(opcode, 11, 8);
89699b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rn = Bits32(opcode, 19, 16);
89709b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rm = Bits32(opcode, 3, 0);
89719b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        setflags = BitIsSet(opcode, 20);
89729b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        shift_n = DecodeImmShiftThumb(opcode, shift_t);
89739b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
89749b381775c532270fd07a90aa1a98750546a768b7Johnny Chen            return false;
89759b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        break;
89769b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    case eEncodingA1:
89779b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rd = Bits32(opcode, 15, 12);
89789b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rn = Bits32(opcode, 19, 16);
89799b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        Rm = Bits32(opcode, 3, 0);
89809b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        setflags = BitIsSet(opcode, 20);
89819b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        shift_n = DecodeImmShiftARM(opcode, shift_t);
89821f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
89839b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
89849b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        if (Rd == 15 && setflags)
89851f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc (opcode, encoding);
89869b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        break;
89879b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    default:
89889b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
89899b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    }
89909b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    // Read the register value from register Rn.
89919b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t val1 = ReadCoreReg(Rn, &success);
89929b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if (!success)
89939b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
89949b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
89959b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    // Read the register value from register Rm.
89969b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    uint32_t val2 = ReadCoreReg(Rm, &success);
89979b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if (!success)
89989b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
89999b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
9000a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9001a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen    if (!success)
9002a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        return false;
90039b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
90049b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
90059b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    EmulateInstruction::Context context;
90069b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
90079b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    context.SetNoArgs();
90089b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
90099b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        return false;
90109b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
90119b381775c532270fd07a90aa1a98750546a768b7Johnny Chen    return true;
90129b381775c532270fd07a90aa1a98750546a768b7Johnny Chen}
90139b381775c532270fd07a90aa1a98750546a768b7Johnny Chen
901415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result
901515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register.  It can optionally update the condition flags based on the result.
901615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool
90177bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
901815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{
901915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0
902015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    // ARM pseudo code...
902115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    if ConditionPassed() then
902215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        EncodingSpecificOperations();
902315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
902415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        R[d] = result;
902515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if setflags then
902615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            APSR.N = result<31>;
902715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            APSR.Z = IsZeroBit(result);
902815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            APSR.C = carry;
902915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            APSR.V = overflow;
903015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif
903115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
903215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    bool success = false;
903315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
903415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t Rd; // the destination register
903515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t Rn; // the first operand
903615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    bool setflags;
903715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
903815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    switch (encoding) {
903915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    case eEncodingT1:
904015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rd = Bits32(opcode, 2, 0);
904115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rn = Bits32(opcode, 5, 3);
904215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        setflags = !InITBlock();
904315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
904415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        break;
904515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    case eEncodingT2:
904615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rd = Rn = Bits32(opcode, 10, 8);
904715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        setflags = !InITBlock();
904815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
904915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        break;
905015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    case eEncodingT3:
905115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rd = Bits32(opcode, 11, 8);
905215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rn = Bits32(opcode, 19, 16);
905315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        setflags = BitIsSet(opcode, 20);
905415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
905515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
905615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
905715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rd == 15 && setflags)
90587bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return EmulateCMPImm (opcode, eEncodingT2);
905915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
9060bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if Rn == '1101' then SEE SUB (SP minus immediate);
906115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rn == 13)
90627bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return EmulateSUBSPImm (opcode, eEncodingT2);
906315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
906415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
906515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
906615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            return false;
906715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        break;
906815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    case eEncodingT4:
906915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rd = Bits32(opcode, 11, 8);
907015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rn = Bits32(opcode, 19, 16);
907115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        setflags = BitIsSet(opcode, 20);
907215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
907315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
907415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // if Rn == '1111' then SEE ADR;
907515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rn == 15)
90767bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return EmulateADR (opcode, eEncodingT2);
907715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
907815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // if Rn == '1101' then SEE SUB (SP minus immediate);
907915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rn == 13)
90807bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return EmulateSUBSPImm (opcode, eEncodingT3);
908115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
908215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (BadReg(Rd))
908315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            return false;
908415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        break;
908515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    default:
908615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        return false;
908715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    }
908815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    // Read the register value from the operand register Rn.
908915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
909015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    if (!success)
909115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        return false;
909215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
909315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
909415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
909515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    EmulateInstruction::Context context;
909615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
909715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    context.SetNoArgs ();
909815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
909915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
910015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        return false;
910115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
910215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    return true;
910315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen}
910415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
910515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// This instruction subtracts an immediate value from a register value, and writes the result
910615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen// to the destination register.  It can optionally update the condition flags based on the result.
910715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chenbool
91087bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
910915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen{
911015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#if 0
911115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    // ARM pseudo code...
911215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    if ConditionPassed() then
911315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        EncodingSpecificOperations();
911415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
911515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if d == 15 then
911615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            ALUWritePC(result); // setflags is always FALSE here
911715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        else
911815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            R[d] = result;
911915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen            if setflags then
912015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen                APSR.N = result<31>;
912115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen                APSR.Z = IsZeroBit(result);
912215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen                APSR.C = carry;
912315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen                APSR.V = overflow;
912415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen#endif
912515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
912615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    bool success = false;
912715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
912815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t Rd; // the destination register
912915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t Rn; // the first operand
913015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    bool setflags;
913115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
913215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    switch (encoding) {
913315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    case eEncodingA1:
913415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rd = Bits32(opcode, 15, 12);
913515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        Rn = Bits32(opcode, 19, 16);
913615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        setflags = BitIsSet(opcode, 20);
913715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
913815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
9139bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if Rn == '1111' && S == '0' then SEE ADR;
914015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rn == 15 && !setflags)
91417bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return EmulateADR (opcode, eEncodingA2);
914215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
9143bb48f0bb876db5ef13d6084b28aba1cf21f0bb7cCaroline Tice        // if Rn == '1101' then SEE SUB (SP minus immediate);
914415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rn == 13)
91457bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return EmulateSUBSPImm (opcode, eEncodingA1);
914615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
914715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
914815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        if (Rd == 15 && setflags)
91491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return EmulateSUBSPcLrEtc (opcode, encoding);
915015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        break;
915115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    default:
915215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        return false;
915315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    }
915415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    // Read the register value from the operand register Rn.
915515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    uint32_t reg_val = ReadCoreReg(Rn, &success);
915615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    if (!success)
915715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        return false;
915815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
915915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
916015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
916115a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    EmulateInstruction::Context context;
916215a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    context.type = EmulateInstruction::eContextImmediate;
916315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    context.SetNoArgs ();
916415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
916515a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
916615a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        return false;
916715a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
916815a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen    return true;
916915a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen}
917015a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen
91712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
91722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// immediate value.  It updates the condition flags based on the result, and discards the result.
91732115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
91747bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
91752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
91762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
91772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
91782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
91792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
91802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR imm32;
91812115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.N = result<31>;
91822115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.Z = IsZeroBit(result);
91832115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.C = carry;
91842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // APSR.V unchanged
91852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
91862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
91872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
91882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
91897bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
91902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
91912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rn;
91922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
91932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
91942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
91952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
91962115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
91972115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
91987bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
91992115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (BadReg(Rn))
92002115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
92012115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
92022115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
92032115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
92047bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
92052115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
92062115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
92072115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
92092115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
92112115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
92122115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
92132115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92142115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92152115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ imm32;
92162115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92172115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
92182115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
92192115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
92202115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92212115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteFlags(context, result, carry))
92222115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92232115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
92242115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
92252115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
92262115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92272115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
92282115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// optionally-shifted register value.  It updates the condition flags based on the result, and discards
92292115b4131b0e427341959fb4007e0173bf71778dJohnny Chen// the result.
92302115b4131b0e427341959fb4007e0173bf71778dJohnny Chenbool
92317bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
92322115b4131b0e427341959fb4007e0173bf71778dJohnny Chen{
92332115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#if 0
92342115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    // ARM pseudo code...
92352115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    if ConditionPassed() then
92362115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EncodingSpecificOperations();
92372115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
92382115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        result = R[n] EOR shifted;
92392115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.N = result<31>;
92402115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.Z = IsZeroBit(result);
92412115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        APSR.C = carry;
92422115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // APSR.V unchanged
92432115b4131b0e427341959fb4007e0173bf71778dJohnny Chen#endif
92442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92452115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    bool success = false;
92462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92477bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
92482115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    {
92492115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t Rn, Rm;
92502115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        ARM_ShifterType shift_t;
92512115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
92522115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t carry;
92532115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        switch (encoding)
92542115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        {
92552115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingT1:
92562115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
92572115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
92583dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
92592115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            if (BadReg(Rn) || BadReg(Rm))
92602115b4131b0e427341959fb4007e0173bf71778dJohnny Chen                return false;
92612115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
92622115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        case eEncodingA1:
92632115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rn = Bits32(opcode, 19, 16);
92642115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            Rm = Bits32(opcode, 3, 0);
92653dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
92662115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            break;
92672115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        default:
92682115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92692115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        }
92702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92712115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the first operand.
92722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
92732115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
92742115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92752115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92762115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // Read the second operand.
92772115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
92782115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!success)
92792115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92802115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
9281a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9282a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
9283a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
92842115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        uint32_t result = val1 ^ shifted;
92852115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92862115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        EmulateInstruction::Context context;
92872115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.type = EmulateInstruction::eContextImmediate;
92882115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        context.SetNoArgs ();
92892115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
92902115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        if (!WriteFlags(context, result, carry))
92912115b4131b0e427341959fb4007e0173bf71778dJohnny Chen            return false;
92922115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    }
92932115b4131b0e427341959fb4007e0173bf71778dJohnny Chen    return true;
92942115b4131b0e427341959fb4007e0173bf71778dJohnny Chen}
92952115b4131b0e427341959fb4007e0173bf71778dJohnny Chen
9296de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9297de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result.
9298de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool
92997bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9300de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{
9301de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0
9302de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    // ARM pseudo code...
9303de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if ConditionPassed() then
9304de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EncodingSpecificOperations();
9305de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        result = R[n] AND imm32;
9306de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.N = result<31>;
9307de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.Z = IsZeroBit(result);
9308de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.C = carry;
9309de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // APSR.V unchanged
9310de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif
9311de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9312de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    bool success = false;
9313de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
93147bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
9315de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    {
9316de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t Rn;
9317de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9318de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9319de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        switch (encoding)
9320de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        {
9321de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingT1:
9322de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
9323de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9324de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            if (BadReg(Rn))
9325de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen                return false;
9326de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
9327de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingA1:
9328de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
9329de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9330de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
9331de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        default:
9332de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9333de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        }
9334de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9335de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // Read the first operand.
9336de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
9337de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!success)
9338de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9339de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9340de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t result = val1 & imm32;
9341de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9342de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EmulateInstruction::Context context;
9343de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
9344de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.SetNoArgs ();
9345de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9346de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!WriteFlags(context, result, carry))
9347de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9348de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    }
9349de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    return true;
9350de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen}
9351de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9352de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9353de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen// It updates the condition flags based on the result, and discards the result.
9354de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chenbool
93557bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9356de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen{
9357de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#if 0
9358de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    // ARM pseudo code...
9359de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    if ConditionPassed() then
9360de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EncodingSpecificOperations();
9361de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9362de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        result = R[n] AND shifted;
9363de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.N = result<31>;
9364de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.Z = IsZeroBit(result);
9365de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        APSR.C = carry;
9366de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // APSR.V unchanged
9367de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen#endif
9368de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9369de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    bool success = false;
9370de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
93717bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    if (ConditionPassed(opcode))
9372de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    {
9373de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t Rn, Rm;
9374de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        ARM_ShifterType shift_t;
9375de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t shift_n; // the shift applied to the value read from Rm
9376de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t carry;
9377de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        switch (encoding)
9378de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        {
9379de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingT1:
9380de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 2, 0);
9381de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rm = Bits32(opcode, 5, 3);
9382de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            shift_t = SRType_LSL;
9383de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            shift_n = 0;
9384ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen            break;
9385de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingT2:
9386de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
9387de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rm = Bits32(opcode, 3, 0);
93883dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9389de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            if (BadReg(Rn) || BadReg(Rm))
9390de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen                return false;
9391de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
9392de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        case eEncodingA1:
9393de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rn = Bits32(opcode, 19, 16);
9394de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            Rm = Bits32(opcode, 3, 0);
93953dd06057d611b9d73c9b7ce69011c739dc40c6eeJohnny Chen            shift_n = DecodeImmShiftARM(opcode, shift_t);
9396de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            break;
9397de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        default:
9398de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9399de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        }
9400de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9401de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // Read the first operand.
9402de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t val1 = ReadCoreReg(Rn, &success);
9403de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!success)
9404de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9405de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9406de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // Read the second operand.
9407de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t val2 = ReadCoreReg(Rm, &success);
9408de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!success)
9409de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9410de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9411a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9412a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
9413a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
9414de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        uint32_t result = val1 & shifted;
9415de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9416de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        EmulateInstruction::Context context;
9417de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.type = EmulateInstruction::eContextImmediate;
9418de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        context.SetNoArgs ();
9419de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
9420de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        if (!WriteFlags(context, result, carry))
9421de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen            return false;
9422de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    }
9423de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen    return true;
9424de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen}
9425d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9426d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.216 SUB (SP minus register)
9427d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
9428d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9429d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
9430d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
9431d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if ConditionPassed() then
9432d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        EncodingSpecificOperations();
9433d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9434061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9435d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        if d == 15 then // Can only occur for ARM encoding
9436d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            ALUWritePC(result); // setflags is always FALSE here
9437d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        else
9438d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            R[d] = result;
9439d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            if setflags then
9440d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                APSR.N = result<31>;
9441d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                APSR.Z = IsZeroBit(result);
9442d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                APSR.C = carry;
9443d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                APSR.V = overflow;
9444d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
9445d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9446d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    bool success = false;
9447d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9448d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
9449d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
9450d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        uint32_t d;
9451d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        uint32_t m;
9452d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        bool setflags;
9453d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        ARM_ShifterType shift_t;
9454d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        uint32_t shift_n;
9455d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9456d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
9457d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
9458d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            case eEncodingT1:
9459061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9460d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                d = Bits32 (opcode, 11, 8);
9461d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                m = Bits32 (opcode, 3, 0);
9462d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                setflags = BitIsSet (opcode, 20);
9463d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9464d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9465d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9466d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9467d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9468d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9469d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                    return false;
9470d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9471d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9472d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                if ((d == 15) || BadReg (m))
9473d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                    return false;
9474d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                break;
9475d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9476d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            case eEncodingA1:
9477061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9478d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                d = Bits32 (opcode, 15, 12);
9479d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                m = Bits32 (opcode, 3, 0);
9480d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                setflags = BitIsSet (opcode, 20);
94811f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
9482061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
94831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                if (d == 15 && setflags)
94841f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                    EmulateSUBSPcLrEtc (opcode, encoding);
9485d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9486d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9487d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                shift_n = DecodeImmShiftARM (opcode, shift_t);
9488d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                break;
9489d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9490d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            default:
9491d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice                return false;
9492d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
9493d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9494d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9495d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        uint32_t Rm = ReadCoreReg (m, &success);
9496d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        if (!success)
9497d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            return false;
9498d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9499a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9500a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
9501a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
9502d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9503061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9504d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9505d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        if (!success)
9506d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            return false;
9507d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9508d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9509d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9510d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        EmulateInstruction::Context context;
9511c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
9512c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo sp_reg;
9513c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9514c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo dwarf_reg;
9515c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9516d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9517d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9518ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9519d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice            return false;
9520d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
9521d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
9522d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
9523d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9524d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9525d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.7 ADD (register-shifted register)
9526d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
9527c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline TiceEmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9528d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
9529d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
9530c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice    if ConditionPassed() then
9531c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        EncodingSpecificOperations();
9532c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        shift_n = UInt(R[s]<7:0>);
9533c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9534061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9535c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        R[d] = result;
9536c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        if setflags then
9537c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            APSR.N = result<31>;
9538c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            APSR.Z = IsZeroBit(result);
9539c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            APSR.C = carry;
9540c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            APSR.V = overflow;
9541d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
9542d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9543c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice    bool success = false;
9544d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9545d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
9546d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
9547c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t d;
9548c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t n;
9549c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t m;
9550c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t s;
9551c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        bool setflags;
9552c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        ARM_ShifterType shift_t;
9553c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9554d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
9555d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
9556c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            case eEncodingA1:
9557c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9558c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                d = Bits32 (opcode, 15, 12);
9559c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                n = Bits32 (opcode, 19, 16);
9560c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                m = Bits32 (opcode, 3, 0);
9561c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                s = Bits32 (opcode, 11, 8);
9562c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9563061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9564c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                setflags = BitIsSet (opcode, 20);
9565c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9566c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9567c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9568c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9569c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                    return false;
9570c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                break;
9571c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9572c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            default:
9573c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice                return false;
9574d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
9575c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9576c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        // shift_n = UInt(R[s]<7:0>);
9577c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t Rs = ReadCoreReg (s, &success);
9578c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        if (!success)
9579c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            return false;
9580c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9581c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t shift_n = Bits32 (Rs, 7, 0);
9582c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9583c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9584c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t Rm = ReadCoreReg (m, &success);
9585c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        if (!success)
9586c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            return false;
9587c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9588a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9589a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
9590a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
9591a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen
9592061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9593c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
9594c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        if (!success)
9595c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            return false;
9596c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9597c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9598c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9599c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        // R[d] = result;
9600c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        EmulateInstruction::Context context;
9601c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
9602c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo reg_n;
9603c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9604c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo reg_m;
9605c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9606c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9607c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        context.SetRegisterRegisterOperands (reg_n, reg_m);
9608c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9609c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9610c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            return false;
9611c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice
9612c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        // if setflags then
9613c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            // APSR.N = result<31>;
9614c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            // APSR.Z = IsZeroBit(result);
9615c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            // APSR.C = carry;
9616c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            // APSR.V = overflow;
9617c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        if (setflags)
9618c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9619d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
9620d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
9621d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
9622d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9623d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.213 SUB (register)
9624d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
9625d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9626d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
9627d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
96284cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice    if ConditionPassed() then
96294cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        EncodingSpecificOperations();
96304cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9631061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
96324cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        if d == 15 then // Can only occur for ARM encoding
96334cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            ALUWritePC(result); // setflags is always FALSE here
96344cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        else
96354cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            R[d] = result;
96364cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            if setflags then
96374cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                APSR.N = result<31>;
96384cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                APSR.Z = IsZeroBit(result);
96394cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                APSR.C = carry;
96404cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                APSR.V = overflow;
9641d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
9642d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
96434cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice    bool success = false;
9644d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9645d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
9646d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
96474cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        uint32_t d;
96484cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        uint32_t n;
96494cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        uint32_t m;
96504cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        bool setflags;
96514cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        ARM_ShifterType shift_t;
96524cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        uint32_t shift_n;
96534cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
9654d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
9655d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
96564cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            case eEncodingT1:
96574cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
96584cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                d = Bits32 (opcode, 2, 0);
96594cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                n = Bits32 (opcode, 5, 3);
96604cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                m = Bits32 (opcode, 8, 6);
96614cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                setflags = !InITBlock();
96624cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96634cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // (shift_t, shift_n) = (SRType_LSL, 0);
96644cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                shift_t = SRType_LSL;
96654cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                shift_n = 0;
96664cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96674cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                break;
96684cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96694cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            case eEncodingT2:
9670061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rd == �1111� && S == �1� then SEE CMP (register);
9671061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rn == �1101� then SEE SUB (SP minus register);
9672061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
96734cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                d = Bits32 (opcode, 11, 8);
96744cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                n = Bits32 (opcode, 19, 16);
96754cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                m = Bits32 (opcode, 3, 0);
96764cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                setflags = BitIsSet (opcode, 20);
96774cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96784cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
96794cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                shift_n = DecodeImmShiftThumb (opcode, shift_t);
96804cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96814cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
96824cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
96834cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                    return false;
96844cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96854cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                break;
96864cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96874cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            case eEncodingA1:
9688061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rn == �1101� then SEE SUB (SP minus register);
9689061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
96904cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                d = Bits32 (opcode, 15, 12);
96914cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                n = Bits32 (opcode, 19, 16);
96924cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                m = Bits32 (opcode, 3, 0);
96934cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                setflags = BitIsSet (opcode, 20);
96941f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
9695061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
96961f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                if ((d == 15) && setflags)
96971f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                    EmulateSUBSPcLrEtc (opcode, encoding);
96984cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
96994cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
97004cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                shift_n = DecodeImmShiftARM (opcode, shift_t);
97014cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
97024cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                break;
97034cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
97044cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            default:
97054cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                return false;
9706d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
97074cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
97084cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
97094cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        uint32_t Rm = ReadCoreReg (m, &success);
97104cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        if (!success)
97114cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            return false;
97124cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
9713a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9714a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen        if (!success)
9715a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            return false;
97164cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
9717061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
97184cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
97194cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        if (!success)
97204cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            return false;
97214cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
97224cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
97234cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
97244cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        // if d == 15 then // Can only occur for ARM encoding
97254cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            // ALUWritePC(result); // setflags is always FALSE here
97264cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        // else
97274cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            // R[d] = result;
97284cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            // if setflags then
97294cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // APSR.N = result<31>;
97304cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // APSR.Z = IsZeroBit(result);
97314cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // APSR.C = carry;
97324cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice                // APSR.V = overflow;
97334cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
97344cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        EmulateInstruction::Context context;
9735c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.type = eContextArithmetic;
9736c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo reg_n;
9737c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9738c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo reg_m;
9739c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
97404cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        context.SetRegisterRegisterOperands (reg_n, reg_m);
97414cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
9742ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
97434cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice            return false;
9744d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
9745d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
9746d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
97474cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice
9748d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.202 STREX
97495168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
97505168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9751d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
9752d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9753d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
9754d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
97555168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice    if ConditionPassed() then
97565168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
97575168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        address = R[n] + imm32;
97585168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        if ExclusiveMonitorsPass(address,4) then
97595168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            MemA[address,4] = R[t];
97605168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            R[d] = 0;
97615168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        else
97625168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            R[d] = 1;
9763d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
9764d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
97655168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice    bool success = false;
9766d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9767d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
9768d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
97695168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        uint32_t d;
97705168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        uint32_t t;
97715168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        uint32_t n;
97725168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        uint32_t imm32;
97735168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
97745168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
9775d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
9776d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
97775168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            case eEncodingT1:
9778061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
97795168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                d = Bits32 (opcode, 11, 8);
97805168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                t = Bits32 (opcode, 15, 12);
97815168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                n = Bits32 (opcode, 19, 16);
97825168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
97835168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
97845168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
97855168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                if (BadReg (d) || BadReg (t) || (n == 15))
97865168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                  return false;
97875168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
97885168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                // if d == n || d == t then UNPREDICTABLE;
97895168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                if ((d == n) || (d == t))
97905168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                  return false;
97915168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
97925168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                break;
97935168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
97945168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            case eEncodingA1:
97955168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
97965168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                d = Bits32 (opcode, 15, 12);
97975168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                t = Bits32 (opcode, 3, 0);
97985168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                n = Bits32 (opcode, 19, 16);
97995168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                imm32 = 0;
98005168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98015168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
98025168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                if ((d == 15) || (t == 15) || (n == 15))
98035168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                    return false;
98045168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98055168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                // if d == n || d == t then UNPREDICTABLE;
98065168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                if ((d == n) || (d == t))
98075168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                    return false;
98085168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98095168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                break;
98105168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98115168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            default:
98125168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                return false;
98135168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        }
98145168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98155168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        // address = R[n] + imm32;
98165168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
98175168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        if (!success)
98185168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            return false;
98195168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98205168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        addr_t address = Rn + imm32;
98215168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
9822c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
9823c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9824c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
9825c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
98265168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        EmulateInstruction::Context context;
98275168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        context.type = eContextRegisterStore;
98285168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
98295168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98305168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        // if ExclusiveMonitorsPass(address,4) then
98315168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
98325168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        //                                                         always return true.
98335168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        if (true)
98345168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        {
98355168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            // MemA[address,4] = R[t];
98365168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
98375168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            if (!success)
98385168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                return false;
98395168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98405168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            if (!MemAWrite (context, address, Rt, addr_byte_size))
98415168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                return false;
98425168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice
98435168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            // R[d] = 0;
98445168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
98455168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                return false;
98465168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        }
98475168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        else
98485168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice        {
98495168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            // R[d] = 1;
98505168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
98515168b6c7119735b6f087ccfcd9ed58811bbb0e32Caroline Tice                return false;
9852d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
9853d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
9854d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
9855d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
9856d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9857d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.197 STRB (immediate, ARM)
9858d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
9859d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9860d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
9861d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
9862ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice    if ConditionPassed() then
9863ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        EncodingSpecificOperations();
9864ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9865ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        address = if index then offset_addr else R[n];
9866ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        MemU[address,1] = R[t]<7:0>;
9867ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if wback then R[n] = offset_addr;
9868d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
9869d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9870ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice    bool success = false;
9871d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9872d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
9873d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
9874ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        uint32_t t;
9875ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        uint32_t n;
9876ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        uint32_t imm32;
9877ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        bool index;
9878ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        bool add;
9879ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        bool wback;
9880ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9881d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
9882d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
9883ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            case eEncodingA1:
9884061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && W == �1� then SEE STRBT;
9885ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9886ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                t = Bits32 (opcode, 15, 12);
9887ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                n = Bits32 (opcode, 19, 16);
9888ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                imm32 = Bits32 (opcode, 11, 0);
9889ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9890061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9891ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                index = BitIsSet (opcode, 24);
9892ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                add = BitIsSet (opcode, 23);
9893ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9894ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9895ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                // if t == 15 then UNPREDICTABLE;
9896ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                if (t == 15)
9897ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                    return false;
9898ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9899ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9900ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                if (wback && ((n == 15) || (n == t)))
9901ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                    return false;
9902ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9903ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                break;
9904ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9905ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            default:
9906ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                return false;
9907ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        }
9908ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9909ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9910ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
9911ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (!success)
9912ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            return false;
9913ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9914ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        addr_t offset_addr;
9915ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (add)
9916ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            offset_addr = Rn + imm32;
9917ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        else
9918ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            offset_addr = Rn - imm32;
9919ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9920ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        // address = if index then offset_addr else R[n];
9921ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        addr_t address;
9922ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (index)
9923ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            address = offset_addr;
9924ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        else
9925ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            address = Rn;
9926ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9927ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        // MemU[address,1] = R[t]<7:0>;
9928ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        uint32_t Rt = ReadCoreReg (t, &success);
9929ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (!success)
9930ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            return false;
9931ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9932c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
9933c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9934c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
9935c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9936ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        EmulateInstruction::Context context;
9937ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        context.type = eContextRegisterStore;
9938ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9939ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9940ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9941ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice            return false;
9942ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice
9943ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        // if wback then R[n] = offset_addr;
9944ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        if (wback)
9945ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice        {
9946523c554292bc09fd8519379d628b5e9090acbd36Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9947ef440003bffefbe10c960d5eea92193f5269be9aCaroline Tice                return false;
9948d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
9949d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
9950d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
9951d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
9952d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9953d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.194 STR (immediate, ARM)
9954d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
9955d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9956d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
9957d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
9958d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice    if ConditionPassed() then
9959d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        EncodingSpecificOperations();
9960d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9961d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        address = if index then offset_addr else R[n];
9962d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9963d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if wback then R[n] = offset_addr;
9964d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
9965d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9966d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice    bool success = false;
9967d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
9968d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
9969d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
9970d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        uint32_t t;
9971d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        uint32_t n;
9972d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        uint32_t imm32;
9973d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        bool index;
9974d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        bool add;
9975d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        bool wback;
9976d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
9977d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
9978d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
9979d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
9980d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
9981d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            case eEncodingA1:
9982061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && W == �1� then SEE STRT;
9983061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9984d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9985d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                t = Bits32 (opcode, 15, 12);
9986d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                n = Bits32 (opcode, 19, 16);
9987d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                imm32 = Bits32 (opcode, 11, 0);
9988d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
9989061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9990d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                index = BitIsSet (opcode, 24);
9991d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                add = BitIsSet (opcode, 23);
9992d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9993d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
9994d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9995d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                if (wback && ((n == 15) || (n == t)))
9996d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                    return false;
9997d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
9998d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                break;
9999d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10000d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            default:
10001d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                return false;
10002d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        }
10003d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10004d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10005d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
10006d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if (!success)
10007d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            return false;
10008d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10009d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        addr_t offset_addr;
10010d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if (add)
10011d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            offset_addr = Rn + imm32;
10012d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        else
10013d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            offset_addr = Rn - imm32;
10014d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10015d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        // address = if index then offset_addr else R[n];
10016d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        addr_t address;
10017d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if (index)
10018d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            address = offset_addr;
10019d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        else
10020d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            address = Rn;
10021d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10022c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10023c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10024c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
10025c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10026d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        EmulateInstruction::Context context;
10027d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        context.type = eContextRegisterStore;
10028d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10029d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10030d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10031d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        uint32_t Rt = ReadCoreReg (t, &success);
10032d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if (!success)
10033d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            return false;
10034d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10035d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if (t == 15)
10036d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        {
10037e98b958df160cef9f2e816b4d86342f42a1c4025Caroline Tice            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10038d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            if (!success)
10039d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                return false;
10040d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10041d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            if (!MemUWrite (context, address, pc_value, addr_byte_size))
10042d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                return false;
10043d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        }
10044d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        else
10045d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        {
10046d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            if (!MemUWrite (context, address, Rt, addr_byte_size))
10047d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                  return false;
10048d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        }
10049d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10050d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        // if wback then R[n] = offset_addr;
10051d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        if (wback)
10052d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice        {
10053d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            context.type = eContextAdjustBaseRegister;
10054d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            context.SetImmediate (offset_addr);
10055d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice
10056d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10057d42b3cc76caa3d85a0d8dc6c97b89160e95229f9Caroline Tice                return false;
10058d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
10059d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
10060d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
10061d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
10062d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10063d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.66 LDRD (immediate)
100641697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
100651697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10066d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
10067d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10068d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
10069d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
100701697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice    if ConditionPassed() then
100711697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
100721697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
100731697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        address = if index then offset_addr else R[n];
100741697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        R[t] = MemA[address,4];
100751697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        R[t2] = MemA[address+4,4];
100761697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if wback then R[n] = offset_addr;
10077d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
10078d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
100791697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice    bool success = false;
10080d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10081d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
10082d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
100831697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        uint32_t t;
100841697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        uint32_t t2;
100851697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        uint32_t n;
100861697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        uint32_t imm32;
100871697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        bool index;
100881697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        bool add;
100891697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        bool wback;
100901697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
10091d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
10092d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
100931697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            case eEncodingT1:
10094061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //if P == �0� && W == �0� then SEE �Related encodings�;
10095061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //if Rn == �1111� then SEE LDRD (literal);
10096061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
100971697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                t = Bits32 (opcode, 15, 12);
100981697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                t2 = Bits32 (opcode, 11, 8);
100991697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                n = Bits32 (opcode, 19, 16);
101001697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
101011697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
10102061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
101031697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                index = BitIsSet (opcode, 24);
101041697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                add = BitIsSet (opcode, 23);
101051697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                wback = BitIsSet (opcode, 21);
101061697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101071697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                //if wback && (n == t || n == t2) then UNPREDICTABLE;
101081697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                if (wback && ((n == t) || (n == t2)))
101091697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                    return false;
101101697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101111697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
101121697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                if (BadReg (t) || BadReg (t2) || (t == t2))
101131697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                    return false;
101141697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101151697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                break;
101161697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101171697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            case eEncodingA1:
10118061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //if Rn == �1111� then SEE LDRD (literal);
10119061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //if Rt<0> == �1� then UNPREDICTABLE;
101201697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
101211697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                t = Bits32 (opcode, 15, 12);
10122eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                if (BitIsSet (t, 0))
10123eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                    return false;
101241697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                t2 = t + 1;
101251697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                n = Bits32 (opcode, 19, 16);
101261697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
101271697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
10128061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
101291697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                index = BitIsSet (opcode, 24);
101301697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                add = BitIsSet (opcode, 23);
101311697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
101321697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
10133061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //if P == �0� && W == �1� then UNPREDICTABLE;
101341697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
101351697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                    return false;
101361697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101371697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                //if wback && (n == t || n == t2) then UNPREDICTABLE;
101381697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                if (wback && ((n == t) || (n == t2)))
101391697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                    return false;
101401697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101411697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                //if t2 == 15 then UNPREDICTABLE;
101421697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                if (t2 == 15)
101431697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                    return false;
101441697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101451697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                break;
101461697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101471697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            default:
101481697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                return false;
101491697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        }
101501697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101511697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
101521697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
101531697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (!success)
101541697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            return false;
101551697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101561697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        addr_t offset_addr;
101571697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (add)
101581697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                  offset_addr = Rn + imm32;
101591697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        else
101601697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            offset_addr = Rn - imm32;
101611697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101621697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        //address = if index then offset_addr else R[n];
101631697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        addr_t address;
101641697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (index)
101651697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            address = offset_addr;
101661697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        else
101671697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            address = Rn;
101681697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101691697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        //R[t] = MemA[address,4];
10170c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10171c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
101721697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101731697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        EmulateInstruction::Context context;
101741697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        context.type = eContextRegisterLoad;
101751697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        context.SetRegisterPlusOffset (base_reg, address - Rn);
101761697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101771697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
101781697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
101791697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (!success)
101801697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            return false;
101811697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101821697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
101831697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            return false;
101841697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101851697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        //R[t2] = MemA[address+4,4];
101861697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101871697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
101881697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
101891697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (!success)
101901697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            return false;
101911697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101921697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
101931697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            return false;
101941697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
101951697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        //if wback then R[n] = offset_addr;
101961697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        if (wback)
101971697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice        {
101981697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            context.type = eContextAdjustBaseRegister;
101991697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            context.SetAddress (offset_addr);
102001697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice
102011697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
102021697dd77af1f72a34cd2ce881e865370cf1593c8Caroline Tice                return false;
10203d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
10204d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
10205d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
10206d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
10207d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10208d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.68 LDRD (register)
10209eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10210eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10211d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
10212d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10213d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
10214d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
10215eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice    if ConditionPassed() then
10216eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        EncodingSpecificOperations();
10217eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10218eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        address = if index then offset_addr else R[n];
10219eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        R[t] = MemA[address,4];
10220eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        R[t2] = MemA[address+4,4];
10221eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if wback then R[n] = offset_addr;
10222d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
10223d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10224eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice    bool success = false;
10225d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10226d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    if (ConditionPassed(opcode))
10227d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    {
10228eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t t;
10229eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t t2;
10230eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t n;
10231eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t m;
10232eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        bool index;
10233eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        bool add;
10234eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        bool wback;
10235d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10236d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        switch (encoding)
10237d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
10238eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            case eEncodingA1:
10239061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rt<0> == �1� then UNPREDICTABLE;
10240eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10241eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                t = Bits32 (opcode, 15, 12);
10242eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                if (BitIsSet (t, 0))
10243eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                    return false;
10244eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                t2 = t + 1;
10245eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                n = Bits32 (opcode, 19, 16);
10246eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                m = Bits32 (opcode, 3, 0);
10247d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10248061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10249eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                index = BitIsSet (opcode, 24);
10250eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                add = BitIsSet (opcode, 23);
10251eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10252d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10253061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && W == �1� then UNPREDICTABLE;
10254eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10255eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  return false;
10256d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10257eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10258eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10259eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  return false;
10260d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10261eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10262eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10263eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  return false;
10264d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10265eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10266eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                if ((ArchVersion() < 6) && wback && (m == n))
10267eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                  return false;
10268eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                break;
10269d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10270eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            default:
10271eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                return false;
10272d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
10273d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10274eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
10275eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (!success)
10276eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            return false;
10277c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10278c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10279d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10280eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t Rm = ReadCoreReg (m, &success);
10281eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (!success)
10282eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            return false;
10283c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo offset_reg;
10284c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10285d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10286eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10287eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        addr_t offset_addr;
10288eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (add)
10289eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            offset_addr = Rn + Rm;
10290eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        else
10291eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            offset_addr = Rn - Rm;
10292d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10293eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        // address = if index then offset_addr else R[n];
10294eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        addr_t address;
10295eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (index)
10296eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            address = offset_addr;
10297eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        else
10298eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            address = Rn;
10299d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10300eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        EmulateInstruction::Context context;
10301eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        context.type = eContextRegisterLoad;
10302eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10303d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10304eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        // R[t] = MemA[address,4];
10305eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
10306eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10307eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (!success)
10308eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            return false;
10309d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10310eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10311eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            return false;
10312d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10313eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        // R[t2] = MemA[address+4,4];
10314d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10315eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10316eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (!success)
10317eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            return false;
10318d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10319eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10320eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            return false;
10321d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10322eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        // if wback then R[n] = offset_addr;
10323eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice        if (wback)
10324d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        {
10325eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            context.type = eContextAdjustBaseRegister;
10326eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            context.SetAddress (offset_addr);
10327d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10328eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10329eab301f1d38aa05e88ca33e250c3bf78aebd2b87Caroline Tice                return false;
10330d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice        }
10331d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    }
10332d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
10333d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
10334d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10335d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.200 STRD (immediate)
1033674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
1033774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10338d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
10339d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10340d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
10341d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
1034274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    if ConditionPassed() then
1034374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
1034474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1034574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        address = if index then offset_addr else R[n];
1034674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        MemA[address,4] = R[t];
1034774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        MemA[address+4,4] = R[t2];
1034874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if wback then R[n] = offset_addr;
10349d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
10350d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
1035174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    bool success = false;
1035274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1035374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    if (ConditionPassed(opcode))
1035474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    {
1035574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t t;
1035674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t t2;
1035774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t n;
1035874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t imm32;
1035974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        bool index;
1036074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        bool add;
1036174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        bool wback;
1036274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1036374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        switch (encoding)
1036474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        {
1036574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            case eEncodingT1:
10366061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && W == �0� then SEE �Related encodings�;
10367061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
1036874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                t = Bits32 (opcode, 15, 12);
1036974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                t2 = Bits32 (opcode, 11, 8);
1037074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                n = Bits32 (opcode, 19, 16);
1037174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
1037274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10373061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
1037474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                index = BitIsSet (opcode, 24);
1037574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                add = BitIsSet (opcode, 23);
1037674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                wback = BitIsSet (opcode, 21);
1037774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1037874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if wback && (n == t || n == t2) then UNPREDICTABLE;
1037974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (wback && ((n == t) || (n == t2)))
1038074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                    return false;
1038174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1038274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
1038374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if ((n == 15) || BadReg (t) || BadReg (t2))
1038474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                    return false;
1038574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1038674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                break;
1038774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1038874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            case eEncodingA1:
10389061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rt<0> == �1� then UNPREDICTABLE;
1039074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
1039174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                t = Bits32 (opcode, 15, 12);
1039274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (BitIsSet (t, 0))
1039374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                    return false;
1039474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1039574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                t2 = t + 1;
1039674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                n = Bits32 (opcode, 19, 16);
1039774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
1039874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10399061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
1040074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                index = BitIsSet (opcode, 24);
1040174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                add = BitIsSet (opcode, 23);
1040274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
1040374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10404061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && W == �1� then UNPREDICTABLE;
1040574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
1040674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                    return false;
1040774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1040874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
1040974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (wback && ((n == 15) || (n == t) || (n == t2)))
1041074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                    return false;
1041174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1041274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if t2 == 15 then UNPREDICTABLE;
1041374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (t2 == 15)
1041474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                    return false;
1041574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1041674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                break;
1041774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1041874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            default:
1041974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                return false;
1042074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        }
1042174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10422c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10423c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
1042474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1042574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
1042674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1042774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1042874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1042974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1043074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        addr_t offset_addr;
1043174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (add)
1043274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            offset_addr = Rn + imm32;
1043374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        else
1043474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            offset_addr = Rn - imm32;
10435d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
1043674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        //address = if index then offset_addr else R[n];
1043774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        addr_t address;
1043874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (index)
1043974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            address = offset_addr;
1044074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        else
1044174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            address = Rn;
1044274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1044374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        //MemA[address,4] = R[t];
10444c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
10445c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
1044674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1044774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t data = ReadCoreReg (t, &success);
1044874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1044974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1045074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1045174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        EmulateInstruction::Context context;
1045274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        context.type = eContextRegisterStore;
1045374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
1045474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1045574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
1045674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1045774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!MemAWrite (context, address, data, addr_byte_size))
1045874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1045974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1046074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        //MemA[address+4,4] = R[t2];
10461c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
1046274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
1046374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1046474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        data = ReadCoreReg (t2, &success);
1046574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1046674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1046774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1046874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!MemAWrite (context, address + 4, data, addr_byte_size))
1046974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1047074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1047174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        //if wback then R[n] = offset_addr;
1047274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (wback)
1047374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        {
1047474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            context.type = eContextAdjustBaseRegister;
1047574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            context.SetAddress (offset_addr);
1047674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1047774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
1047874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                return false;
1047974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        }
1048074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    }
10481d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice    return true;
10482d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
10483d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10484d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
10485d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice// A8.6.201 STRD (register)
10486d05b4903bb95b07e709986961fe387921dd0e029Caroline Ticebool
10487d05b4903bb95b07e709986961fe387921dd0e029Caroline TiceEmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10488d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice{
10489d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#if 0
1049074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    if ConditionPassed() then
1049174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        EncodingSpecificOperations();
1049274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
1049374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        address = if index then offset_addr else R[n];
1049474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        MemA[address,4] = R[t];
1049574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        MemA[address+4,4] = R[t2];
1049674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if wback then R[n] = offset_addr;
10497d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice#endif
10498d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
1049974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    bool success = false;
1050074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1050174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    if (ConditionPassed(opcode))
1050274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    {
1050374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t t;
1050474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t t2;
1050574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t n;
1050674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t m;
1050774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        bool index;
1050874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        bool add;
1050974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        bool wback;
10510d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
1051174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        switch (encoding)
1051274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        {
1051374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            case eEncodingA1:
10514061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if Rt<0> == �1� then UNPREDICTABLE;
1051574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
1051674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                t = Bits32 (opcode, 15, 12);
1051774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (BitIsSet (t, 0))
1051874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                   return false;
1051974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1052074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                t2 = t+1;
1052174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                n = Bits32 (opcode, 19, 16);
1052274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                m = Bits32 (opcode, 3, 0);
1052374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10524061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
1052574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                index = BitIsSet (opcode, 24);
1052674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                add = BitIsSet (opcode, 23);
1052774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
1052874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10529061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && W == �1� then UNPREDICTABLE;
1053074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
1053174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                   return false;
1053274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1053374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if t2 == 15 || m == 15 then UNPREDICTABLE;
1053474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if ((t2 == 15) || (m == 15))
1053574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                   return false;
1053674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1053774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
1053874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                if (wback && ((n == 15) || (n == t) || (n == t2)))
1053974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                   return false;
1054074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1054174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
105424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if ((ArchVersion() < 6) && wback && (m == n))
1054374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                   return false;
1054474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1054574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                break;
1054674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1054774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            default:
1054874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                return false;
1054974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        }
1055074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10551c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10552c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10553c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo offset_reg;
10554c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10555c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
1055674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1055774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
1055874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1055974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1056074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1056174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t Rm = ReadCoreReg (m, &success);
1056274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1056374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1056474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1056574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
1056674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        addr_t offset_addr;
1056774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (add)
1056874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            offset_addr = Rn + Rm;
1056974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        else
1057074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            offset_addr = Rn - Rm;
1057174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1057274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        // address = if index then offset_addr else R[n];
1057374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        addr_t address;
1057474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (index)
1057574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            address = offset_addr;
1057674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        else
1057774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            address = Rn;
1057874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                          // MemA[address,4] = R[t];
1057974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t Rt = ReadCoreReg (t, &success);
1058074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1058174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1058274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1058374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        EmulateInstruction::Context context;
1058474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        context.type = eContextRegisterStore;
10585c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
1058674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
1058774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1058874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
1058974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1059074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!MemAWrite (context, address, Rt, addr_byte_size))
1059174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1059274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1059374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        // MemA[address+4,4] = R[t2];
1059474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        uint32_t Rt2 = ReadCoreReg (t2, &success);
1059574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!success)
1059674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1059774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
10598c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
1059974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1060074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
1060174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1060274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
1060374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            return false;
1060474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1060574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        // if wback then R[n] = offset_addr;
1060674467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        if (wback)
1060774467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        {
1060874467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            context.type = eContextAdjustBaseRegister;
1060974467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            context.SetAddress (offset_addr);
1061074467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1061174467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
1061274467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice                return false;
1061374467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice
1061474467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice        }
1061574467fe6f301d25e21f5c6bcec4c9ad7d4c1f8b7Caroline Tice    }
1061624bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton    return true;
10617d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice}
10618d05b4903bb95b07e709986961fe387921dd0e029Caroline Tice
106194f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice// A8.6.319 VLDM
106204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
106214f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice// an ARM core register.
106224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Ticebool
106234f6055840a3d5006a60d54c139b1f8975ed0c638Caroline TiceEmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
106244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice{
106254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#if 0
106264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice    if ConditionPassed() then
106274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
106284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        address = if add then R[n] else R[n]-imm32;
10629c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
106304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        for r = 0 to regs-1
106314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            if single_regs then
106324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                S[d+r] = MemA[address,4]; address = address+4;
106334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            else
106344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
106354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // Combine the word-aligned words in the correct order for current endianness.
106364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
106374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice#endif
106384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice    bool success = false;
106404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106414f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice    if (ConditionPassed(opcode))
106424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice    {
10643bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        bool single_regs;
10644bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        bool add;
10645bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        bool wback;
10646bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t d;
10647bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t n;
10648bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t imm32;
10649bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t regs;
10650bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
106514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        switch (encoding)
106524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        {
106534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            case eEncodingT1:
106544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            case eEncodingA1:
10655061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10656061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10657061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �1� && W == �0� then SEE VLDR;
10658061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == U && W == �1� then UNDEFINED;
106594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
106604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
106614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10663061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
106644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                single_regs = false;
106654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                add = BitIsSet (opcode, 23);
106664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                wback = BitIsSet (opcode, 21);
106674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
10668061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
106694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
106704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                n = Bits32 (opcode, 19, 16);
106714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
106724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
10673061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
106744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                regs = Bits32 (opcode, 7, 0) / 2;
106754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
106774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
106784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
106794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
106814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
106824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
106834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                break;
106854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            case eEncodingT2:
106874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            case eEncodingA2:
10688061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10689061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10690061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �1� && W == �0� then SEE VLDR;
10691061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == U && W == �1� then UNDEFINED;
106924f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
106934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
106944f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
106954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10696061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
106974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                single_regs = true;
106984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                add = BitIsSet (opcode, 23);
106994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                wback = BitIsSet (opcode, 21);
107004f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
107014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                n = Bits32 (opcode, 19, 16);
107024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
10703061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
107044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
107054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                regs = Bits32 (opcode, 7, 0);
107064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
107084f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
107094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
107104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
107124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if ((regs == 0) || ((d + regs) > 32))
107134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
107144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                break;
107154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            default:
107174f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                return false;
107184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        }
107194f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
10720c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10721c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
107224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107234f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
107244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        if (!success)
107254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            return false;
107264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        // address = if add then R[n] else R[n]-imm32;
107284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        addr_t address;
107294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        if (add)
107304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            address = Rn;
107314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        else
107324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            address = Rn - imm32;
107334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
10734c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
107354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        EmulateInstruction::Context context;
107364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        if (wback)
107384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        {
107394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            uint32_t value;
107404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            if (add)
107414f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                value = Rn + imm32;
107424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            else
107434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                value = Rn - imm32;
107444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            context.type = eContextAdjustBaseRegister;
107464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            context.SetImmediateSigned (value - Rn);
107474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
107484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                return false;
107494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        }
107514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
107534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
107544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        context.type = eContextRegisterLoad;
107564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        // for r = 0 to regs-1
10758bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        for (uint32_t r = 0; r < regs; ++r)
107594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        {
107604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            if (single_regs)
107614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            {
107624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // S[d+r] = MemA[address,4]; address = address+4;
107634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                context.SetRegisterPlusOffset (base_reg, address - Rn);
107644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
107664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if (!success)
107674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
107684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
107704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
107714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                address = address + 4;
107734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            }
107744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            else
107754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            {
107764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
107774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                context.SetRegisterPlusOffset (base_reg, address - Rn);
107784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
107794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if (!success)
107804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
107814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
107834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
107844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if (!success)
107854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
107864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
107874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                address = address + 8;
107884f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // // Combine the word-aligned words in the correct order for current endianness.
107894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
107904f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                uint64_t data;
10791888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                if (GetByteOrder() == eByteOrderBig)
107924f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                {
107934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    data = word1;
107944f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    data = (data << 32) | word2;
107954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                }
107964f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                else
107974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                {
107984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    data = word2;
107994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    data = (data << 32) | word1;
108004f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                }
108014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice
108024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
108034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice                    return false;
108044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice            }
108054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        }
108064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice    }
108074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice    return true;
108084f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice}
10809bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10810bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice// A8.6.399 VSTM
10811917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10812917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// ARM core register.
10813bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Ticebool
10814bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline TiceEmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10815bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice{
10816bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice#if 0
10817bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice    if ConditionPassed() then
10818bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10819bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        address = if add then R[n] else R[n]-imm32;
10820c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10821bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        for r = 0 to regs-1
10822bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            if single_regs then
10823bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                MemA[address,4] = S[d+r]; address = address+4;
10824bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            else
10825bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // Store as two word-aligned words in the correct order for current endianness.
10826bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10827bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10828bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                address = address+8;
10829bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice#endif
10830bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10831bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice    bool success = false;
10832bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10833bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice    if (ConditionPassed (opcode))
10834bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice    {
10835bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        bool single_regs;
10836bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        bool add;
10837bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        bool wback;
10838bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t d;
10839bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t n;
10840bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t imm32;
10841bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t regs;
10842bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10843bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        switch (encoding)
10844bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        {
10845bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            case eEncodingT1:
10846bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            case eEncodingA1:
10847061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10848061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10849061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �1� && W == �0� then SEE VSTR;
10850061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == U && W == �1� then UNDEFINED;
10851bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10852bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10853bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10854bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10855061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10856bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                single_regs = false;
10857bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                add = BitIsSet (opcode, 23);
10858bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                wback = BitIsSet (opcode, 21);
10859bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10860061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10861bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10862bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                n = Bits32 (opcode, 19, 16);
10863bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
10864bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10865061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10866bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                regs = Bits32 (opcode, 7, 0) / 2;
10867bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10868bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10869bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10870bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10871bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10872bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10873bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10874bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10875bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10876bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                break;
10877bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10878bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            case eEncodingT2:
10879bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            case eEncodingA2:
10880061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10881061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10882061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == �1� && W == �0� then SEE VSTR;
10883061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if P == U && W == �1� then UNDEFINED;
10884bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10885bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10886bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10887bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10888061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10889bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                single_regs = true;
10890bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                add = BitIsSet (opcode, 23);
10891bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                wback = BitIsSet (opcode, 21);
10892bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10893bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                n = Bits32 (opcode, 19, 16);
10894bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10895061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10896bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
10897bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                regs = Bits32 (opcode, 7, 0);
10898bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10899bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10900bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10901bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10902bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10903bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10904bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if ((regs == 0) || ((d + regs) > 32))
10905bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10906bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10907bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                break;
10908bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10909bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            default:
10910bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                return false;
10911bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        }
10912bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10913c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
10914c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10915bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10916bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
10917bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        if (!success)
10918bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            return false;
10919bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10920bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        // address = if add then R[n] else R[n]-imm32;
10921bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        addr_t address;
10922bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        if (add)
10923bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            address = Rn;
10924bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        else
10925bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            address = Rn - imm32;
10926bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10927bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        EmulateInstruction::Context context;
10928c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10929bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        if (wback)
10930bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        {
10931bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            uint32_t value;
10932bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            if (add)
10933bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                value = Rn + imm32;
10934bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            else
10935bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                value = Rn - imm32;
10936bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10937bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            context.type = eContextAdjustBaseRegister;
10938bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            context.SetRegisterPlusOffset (base_reg, value - Rn);
10939bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10940bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10941bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                return false;
10942bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        }
10943bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10944bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
10945bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10946bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10947bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        context.type = eContextRegisterStore;
10948bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        // for r = 0 to regs-1
109497e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t r = 0; r < regs; ++r)
10950bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        {
10951c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
10952bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            if (single_regs)
10953bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            {
10954bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // MemA[address,4] = S[d+r]; address = address+4;
10955bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10956bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if (!success)
10957bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10958c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
10959c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                RegisterInfo data_reg;
10960c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10961bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10962bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if (!MemAWrite (context, address, data, addr_byte_size))
10963bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10964bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10965bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                address = address + 4;
10966bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            }
10967bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            else
10968bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            {
10969bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // // Store as two word-aligned words in the correct order for current endianness.
10970bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10971bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10972bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10973bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                if (!success)
10974bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    return false;
10975bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10976c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                RegisterInfo data_reg;
10977c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10978bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10979888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                if (GetByteOrder() == eByteOrderBig)
10980bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                {
10981bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10982bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10983bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                        return false;
10984bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10985bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10986bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10987bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                        return false;
10988bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                }
10989bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                else
10990bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                {
10991bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10992bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10993bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                        return false;
10994bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
10995bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10996bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10997bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                        return false;
10998bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                }
10999bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                // address = address+8;
11000bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice                address = address + 8;
11001bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice            }
11002bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice        }
11003bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice    }
11004bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice    return true;
11005bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice}
11006bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
11007917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// A8.6.320
11008917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11009917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice// an optional offset.
11010917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Ticebool
11011917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline TiceEmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11012917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice{
11013917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice#if 0
11014917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice    if ConditionPassed() then
11015917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11016917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        base = if n == 15 then Align(PC,4) else R[n];
11017917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        address = if add then (base + imm32) else (base - imm32);
11018917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        if single_reg then
11019917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            S[d] = MemA[address,4];
11020917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        else
11021917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11022917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            // Combine the word-aligned words in the correct order for current endianness.
11023917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            D[d] = if BigEndian() then word1:word2 else word2:word1;
11024917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice#endif
11025917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11026917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice    bool success = false;
11027917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11028917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice    if (ConditionPassed (opcode))
11029917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice    {
11030917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        bool single_reg;
11031917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        bool add;
11032917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        uint32_t imm32;
11033917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        uint32_t d;
11034917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        uint32_t n;
11035917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11036917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        switch (encoding)
11037917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        {
11038917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            case eEncodingT1:
11039917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            case eEncodingA1:
11040061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11041917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                single_reg = false;
11042917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                add = BitIsSet (opcode, 23);
11043917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
11044917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11045917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                // d = UInt(D:Vd); n = UInt(Rn);
11046917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11047917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                n = Bits32 (opcode, 19, 16);
11048917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11049917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                break;
11050917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11051917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            case eEncodingT2:
11052917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            case eEncodingA2:
11053061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11054917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                single_reg = true;
11055917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                add = BitIsSet (opcode, 23);
11056917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
11057917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11058917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                // d = UInt(Vd:D); n = UInt(Rn);
11059917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11060917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                n = Bits32 (opcode, 19, 16);
11061917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11062917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                break;
11063917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11064917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            default:
11065917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                return false;
11066917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        }
11067c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
11068c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11069917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11070917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
11071917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        if (!success)
11072917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            return false;
11073917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11074917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        // base = if n == 15 then Align(PC,4) else R[n];
11075917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        uint32_t base;
11076917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        if (n == 15)
11077917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            base = AlignPC (Rn);
11078917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        else
11079917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            base = Rn;
11080917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11081917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        // address = if add then (base + imm32) else (base - imm32);
11082917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        addr_t address;
11083917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        if (add)
11084917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            address = base + imm32;
11085917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        else
11086917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            address = base - imm32;
11087917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11088917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
11089917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11090917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11091917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        EmulateInstruction::Context context;
11092917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        context.type = eContextRegisterLoad;
11093917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        context.SetRegisterPlusOffset (base_reg, address - base);
11094bf5a66b583ecf050cf82a6bbe7f284863670968aCaroline Tice
11095917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        if (single_reg)
11096917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        {
11097917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            // S[d] = MemA[address,4];
11098917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11099917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            if (!success)
11100917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                return false;
11101917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11102917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11103917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                return false;
11104917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        }
11105917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        else
11106917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        {
11107917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11108917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11109917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            if (!success)
11110917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                return false;
11111917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11112917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11113917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11114917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            if (!success)
11115917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                return false;
11116917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            // // Combine the word-aligned words in the correct order for current endianness.
11117917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            // D[d] = if BigEndian() then word1:word2 else word2:word1;
11118917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            uint64_t data64;
11119888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if (GetByteOrder() == eByteOrderBig)
11120917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            {
11121917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                data64 = word1;
11122917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                data64 = (data64 << 32) | word2;
11123917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            }
11124917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            else
11125917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            {
11126917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                data64 = word2;
11127917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                data64 = (data64 << 32) | word1;
11128917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            }
11129917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice
11130917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11131917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice                return false;
11132917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice        }
11133917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice    }
11134917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice    return true;
11135917ad35280b65c53419eebbd1c07881d08b3e7d9Caroline Tice}
11136424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11137424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice// A8.6.400 VSTR
11138424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11139424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice// optional offset.
11140424652f4258d968dffb5175c4649f6f8afef4217Caroline Ticebool
11141424652f4258d968dffb5175c4649f6f8afef4217Caroline TiceEmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11142424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice{
11143424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice#if 0
11144424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice    if ConditionPassed() then
11145424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11146424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        address = if add then (R[n] + imm32) else (R[n] - imm32);
11147424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        if single_reg then
11148424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            MemA[address,4] = S[d];
11149424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        else
11150424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            // Store as two word-aligned words in the correct order for current endianness.
11151424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11152424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11153424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice#endif
11154424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11155424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice    bool success = false;
11156424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11157424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice    if (ConditionPassed (opcode))
11158424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice    {
11159424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        bool single_reg;
11160424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        bool add;
11161424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        uint32_t imm32;
11162424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        uint32_t d;
11163424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        uint32_t n;
11164424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11165424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        switch (encoding)
11166424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        {
11167424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            case eEncodingT1:
11168424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            case eEncodingA1:
11169061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11170424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                single_reg = false;
11171424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                add = BitIsSet (opcode, 23);
11172424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
11173424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11174424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                // d = UInt(D:Vd); n = UInt(Rn);
11175424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11176424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                n = Bits32 (opcode, 19, 16);
11177424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11178424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11179424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11180424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                    return false;
11181424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11182424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                break;
11183424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11184424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            case eEncodingT2:
11185424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            case eEncodingA2:
11186061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11187424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                single_reg = true;
11188424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                add = BitIsSet (opcode, 23);
11189424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                imm32 = Bits32 (opcode, 7, 0) << 2;
11190424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11191424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                // d = UInt(Vd:D); n = UInt(Rn);
11192424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11193424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                n = Bits32 (opcode, 19, 16);
11194424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11195424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11196424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11197424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                    return false;
11198424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11199424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                break;
11200424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11201424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            default:
11202424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                return false;
11203424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        }
11204424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11205c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
11206c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11207424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11208424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
11209424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        if (!success)
11210424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            return false;
11211424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11212424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11213424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        addr_t address;
11214424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        if (add)
11215424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            address = Rn + imm32;
11216424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        else
11217424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            address = Rn - imm32;
11218424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11219424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        const uint32_t addr_byte_size = GetAddressByteSize();
11220424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11221424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11222c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
11223c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11224424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        EmulateInstruction::Context context;
11225424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        context.type = eContextRegisterStore;
11226424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11227424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11228424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        if (single_reg)
11229424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        {
11230424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            // MemA[address,4] = S[d];
11231424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11232424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            if (!success)
11233424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                return false;
11234424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11235424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            if (!MemAWrite (context, address, data, addr_byte_size))
11236424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                return false;
11237424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        }
11238424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        else
11239424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        {
11240424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            // // Store as two word-aligned words in the correct order for current endianness.
11241424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11242424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11243424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11244424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            if (!success)
11245424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                return false;
11246424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11247888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if (GetByteOrder() == eByteOrderBig)
11248424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            {
11249424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11250424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                    return false;
11251424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11252424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11253424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11254424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                    return false;
11255424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            }
11256424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            else
11257424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            {
11258424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11259424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                    return false;
11260424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice
11261424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11262424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11263424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice                    return false;
11264424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice            }
11265424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice        }
11266424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice    }
11267424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice    return true;
11268424652f4258d968dffb5175c4649f6f8afef4217Caroline Tice}
112699121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
112709121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice// A8.6.307 VLDI1 (multiple single elements)
112719121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
112729121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice// element of each register is loaded.
112739121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Ticebool
112749121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline TiceEmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
112759121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice{
112769121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice#if 0
112779121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice    if ConditionPassed() then
112789121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
112799121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
112809121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
112819121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        for r = 0 to regs-1
112829121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            for e = 0 to elements-1
112839121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                Elem[D[d+r],e,esize] = MemU[address,ebytes];
112849121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                address = address + ebytes;
112859121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice#endif
112869121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
112879121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice    bool success = false;
112889121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
112899121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice    if (ConditionPassed (opcode))
112909121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice    {
112919121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t regs;
112929121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t alignment;
112939121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t ebytes;
112949121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t esize;
112959121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t elements;
112969121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t d;
112979121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t n;
112989121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t m;
112999121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        bool wback;
113009121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        bool register_index;
113019121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113029121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        switch (encoding)
113039121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        {
113049121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            case eEncodingT1:
113059121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            case eEncodingA1:
113069121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            {
113079121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // case type of
11308061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // when �0111�
11309061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                        // regs = 1; if align<1> == �1� then UNDEFINED;
11310061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // when �1010�
11311061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                        // regs = 2; if align == �11� then UNDEFINED;
11312061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // when �0110�
11313061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                        // regs = 3; if align<1> == �1� then UNDEFINED;
11314061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // when �0010�
113159121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                        // regs = 4;
113169121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    // otherwise
11317061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                        // SEE �Related encodings�;
113189121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                uint32_t type = Bits32 (opcode, 11, 8);
113199121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                uint32_t align = Bits32 (opcode, 5, 4);
113209121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                if (type == 7) // '0111'
113219121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                {
113229121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    regs = 1;
113239121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    if (BitIsSet (align, 1))
113249121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                        return false;
113259121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                }
113269121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                else if (type == 10) // '1010'
113279121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                {
113289121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    regs = 2;
113299121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    if (align == 3)
113309121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                        return false;
113319121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113329121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                }
113339121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                else if (type == 6) // '0110'
113349121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                {
113359121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    regs = 3;
113369121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    if (BitIsSet (align, 1))
113379121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                        return false;
113389121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                }
113399121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                else if (type == 2) // '0010'
113409121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                {
113419121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    regs = 4;
113429121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                }
113439121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                else
113449121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    return false;
113459121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
11346061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // alignment = if align == �00� then 1 else 4 << UInt(align);
113479121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                if (align == 0)
113489121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    alignment = 1;
113499121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                else
113509121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    alignment = 4 << align;
113519121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113529121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
113539121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                ebytes = 1 << Bits32 (opcode, 7, 6);
113549121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                esize = 8 * ebytes;
113559121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                elements = 8 / ebytes;
113569121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113579121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
113589121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
113599121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                n = Bits32 (opcode, 19, 15);
113609121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                m = Bits32 (opcode, 3, 0);
113619121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113629121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // wback = (m != 15); register_index = (m != 15 && m != 13);
113639121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                wback = (m != 15);
113649121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                register_index = ((m != 15) && (m != 13));
113659121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113669121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // if d+regs > 32 then UNPREDICTABLE;
113679121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                if ((d + regs) > 32)
113689121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    return false;
113699121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            }
113709121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                break;
113719121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113729121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            default:
113739121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                return false;
113749121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        }
113759121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
11376c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
11377c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
113789121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113799121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
113809121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        if (!success)
113819121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            return false;
113829121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113839121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
113849121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        addr_t address = Rn;
113859121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        if ((address % alignment) != 0)
113869121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            return false;
113879121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113889121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        EmulateInstruction::Context context;
113899121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
113909121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        if (wback)
113919121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        {
113929121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            uint32_t Rm = ReadCoreReg (m, &success);
113939121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            if (!success)
113949121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                return false;
113959121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
113969121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            uint32_t offset;
113979121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            if (register_index)
113989121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                offset = Rm;
113999121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            else
114009121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                offset = 8 * regs;
114019121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
114029121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            uint32_t value = Rn + offset;
114039121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            context.type = eContextAdjustBaseRegister;
114049121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            context.SetRegisterPlusOffset (base_reg, offset);
114059121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
114069121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
114079121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                return false;
114089121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
114099121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        }
114109121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
114119121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        // for r = 0 to regs-1
114127e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t r = 0; r < regs; ++r)
114139121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        {
114149121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            // for e = 0 to elements-1
114159121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            uint64_t assembled_data = 0;
114167e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs            for (uint32_t e = 0; e < elements; ++e)
114179121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            {
114189121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
114199121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                context.type = eContextRegisterLoad;
114209121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                context.SetRegisterPlusOffset (base_reg, address - Rn);
114219121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                uint64_t data = MemURead (context, address, ebytes, 0, &success);
114229121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                if (!success)
114239121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                    return false;
114249121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
114259121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
114269121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
114279121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                // address = address + ebytes;
114289121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                address = address + ebytes;
114299121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            }
114309121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
114319121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice                return false;
114329121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        }
114339121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice    }
114349121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice    return true;
114359121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice}
114369121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice
11437b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice// A8.6.308 VLD1 (single element to one lane)
11438b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice//
11439b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Ticebool
11440b6281b1d94e75876211a589bc9c4e2756feab04eCaroline TiceEmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11441b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice{
11442b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice#if 0
11443b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice    if ConditionPassed() then
11444b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11445b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11446b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11447b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        Elem[D[d],index,esize] = MemU[address,ebytes];
11448b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice#endif
11449b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11450b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice    bool success = false;
11451b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11452b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice    if (ConditionPassed (opcode))
11453b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice    {
11454b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t ebytes;
11455b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t esize;
11456b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t index;
11457b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t alignment;
11458b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t d;
11459b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t n;
11460b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t m;
11461b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        bool wback;
11462b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        bool register_index;
11463b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11464b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        switch (encoding)
11465b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        {
11466b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            case eEncodingT1:
11467b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            case eEncodingA1:
11468b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            {
11469b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                uint32_t size = Bits32 (opcode, 11, 10);
11470b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                uint32_t index_align = Bits32 (opcode, 7, 4);
11471061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if size == �11� then SEE VLD1 (single element to all lanes);
114728d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice                if (size == 3)
114738d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice                   return EmulateVLD1SingleAll (opcode, encoding);
11474b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                // case size of
11475b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                if (size == 0) // when '00'
11476b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                {
11477061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<0> != �0� then UNDEFINED;
11478b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    if (BitIsClear (index_align, 0))
11479b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        return false;
11480b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11481b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11482b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    ebytes = 1;
11483b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    esize = 8;
11484b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    index = Bits32 (index_align, 3, 1);
11485b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    alignment = 1;
11486b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                }
11487061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (size == 1) // when �01�
11488b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                {
11489061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<1> != �0� then UNDEFINED;
11490b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    if (BitIsClear (index_align, 1))
11491b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        return false;
11492b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11493b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11494b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    ebytes = 2;
11495b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    esize = 16;
11496b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    index = Bits32 (index_align, 3, 2);
11497b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11498061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // alignment = if index_align<0> == �0� then 1 else 2;
11499b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    if (BitIsClear (index_align, 0))
11500b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        alignment = 1;
11501b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    else
11502b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        alignment = 2;
11503b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                }
11504061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (size == 2) // when �10�
11505b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                {
11506061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<2> != �0� then UNDEFINED;
11507b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    if (BitIsClear (index_align, 2))
11508b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        return false;
11509b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11510061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11511b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11512b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        return false;
11513b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11514b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11515b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    ebytes = 4;
11516b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    esize = 32;
11517b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    index = Bit32 (index_align, 3);
11518b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11519061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11520b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    if (Bits32 (index_align, 1, 0) == 0)
11521b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        alignment = 1;
11522b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    else
11523b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                        alignment = 4;
11524b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                }
115254a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                else
115264a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                {
115274a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                    return false;
115284a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                }
11529b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11530b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11531b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                n = Bits32 (opcode, 19, 16);
11532b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                m = Bits32 (opcode, 3, 0);
11533b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11534b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11535b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                wback = (m != 15);
11536b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                register_index = ((m != 15) && (m != 13));
11537b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11538b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                if (n == 15)
11539b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                    return false;
11540b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11541b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            }
11542b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                break;
11543b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11544b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            default:
11545b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                return false;
11546b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        }
11547b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11548c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
11549c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11550b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11551b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
11552b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if (!success)
11553b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            return false;
11554b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11555b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11556b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        addr_t address = Rn;
11557b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if ((address % alignment) != 0)
11558b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            return false;
11559b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11560b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        EmulateInstruction::Context context;
11561b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11562b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if (wback)
11563b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        {
11564b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            uint32_t Rm = ReadCoreReg (m, &success);
11565b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            if (!success)
11566b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                return false;
11567b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11568b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            uint32_t offset;
11569b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            if (register_index)
11570b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                offset = Rm;
11571b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            else
11572b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                offset = ebytes;
11573b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11574b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            uint32_t value = Rn + offset;
11575b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11576b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            context.type = eContextAdjustBaseRegister;
11577b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            context.SetRegisterPlusOffset (base_reg, offset);
11578b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11579b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11580b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                return false;
11581b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        }
11582b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11583b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        // Elem[D[d],index,esize] = MemU[address,ebytes];
11584b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint32_t element = MemURead (context, address, esize, 0, &success);
11585b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if (!success)
11586b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            return false;
11587b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11588b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        element = element << (index * esize);
11589b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11590b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11591b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if (!success)
11592b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            return false;
11593b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11594b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint64_t all_ones = -1;
11595b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11596b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                                                          // at element & to the right of element.
11597b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if (index > 0)
115987b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11599b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                                                                     // now mask should be 0's where element goes & 1's
11600b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice                                                                     // everywhere else.
11601b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11602b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11603b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11604b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
11605b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        context.type = eContextRegisterLoad;
11606b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11607b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice            return false;
11608b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice    }
11609b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice    return true;
11610b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice}
11611b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice
116121e542e30870bbced43d8438d125979dc9522ec07Caroline Tice// A8.6.391 VST1 (multiple single elements)
116131e542e30870bbced43d8438d125979dc9522ec07Caroline Tice// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
116141e542e30870bbced43d8438d125979dc9522ec07Caroline Tice// interleaving.  Every element of each register is stored.
116151e542e30870bbced43d8438d125979dc9522ec07Caroline Ticebool
116161e542e30870bbced43d8438d125979dc9522ec07Caroline TiceEmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
116171e542e30870bbced43d8438d125979dc9522ec07Caroline Tice{
116181e542e30870bbced43d8438d125979dc9522ec07Caroline Tice#if 0
116191e542e30870bbced43d8438d125979dc9522ec07Caroline Tice    if ConditionPassed() then
116201e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
116211e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
116221e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
116231e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        for r = 0 to regs-1
116241e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            for e = 0 to elements-1
116251e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                MemU[address,ebytes] = Elem[D[d+r],e,esize];
116261e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                address = address + ebytes;
116271e542e30870bbced43d8438d125979dc9522ec07Caroline Tice#endif
116281e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116291e542e30870bbced43d8438d125979dc9522ec07Caroline Tice    bool success = false;
116301e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116311e542e30870bbced43d8438d125979dc9522ec07Caroline Tice    if (ConditionPassed (opcode))
116321e542e30870bbced43d8438d125979dc9522ec07Caroline Tice    {
116331e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t regs;
116341e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t alignment;
116351e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t ebytes;
116361e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t esize;
116371e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t elements;
116381e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t d;
116391e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t n;
116401e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t m;
116411e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        bool wback;
116421e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        bool register_index;
116431e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116441e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        switch (encoding)
116451e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        {
116461e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            case eEncodingT1:
116471e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            case eEncodingA1:
116481e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            {
116491e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                uint32_t type = Bits32 (opcode, 11, 8);
116501e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                uint32_t align = Bits32 (opcode, 5, 4);
116511e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116521e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // case type of
11653061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                if (type == 7)    // when �0111�
116541e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                {
11655061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // regs = 1; if align<1> == �1� then UNDEFINED;
116561e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    regs = 1;
116571e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    if (BitIsSet (align, 1))
116581e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                        return false;
116591e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                }
11660061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (type == 10) // when �1010�
116611e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                {
11662061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // regs = 2; if align == �11� then UNDEFINED;
116631e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    regs = 2;
116641e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    if (align == 3)
116651e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                        return false;
116661e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                }
11667061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (type == 6) // when �0110�
116681e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                {
11669061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // regs = 3; if align<1> == �1� then UNDEFINED;
116701e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    regs = 3;
116711e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    if (BitIsSet (align, 1))
116721e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                        return false;
116731e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                }
11674061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (type == 2) // when �0010�
116751e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    // regs = 4;
116761e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    regs = 4;
116771e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                else // otherwise
11678061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // SEE �Related encodings�;
116791e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    return false;
116801e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
11681061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // alignment = if align == �00� then 1 else 4 << UInt(align);
116821e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                if (align == 0)
11683a1c7e46b8260cba74e04d4ae0f748c602148deb9Johnny Chen                    alignment = 1;
116841e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                else
116851e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    alignment = 4 << align;
116861e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116871e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
116881e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                ebytes = 1 << Bits32 (opcode,7, 6);
116891e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                esize = 8 * ebytes;
116901e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                elements = 8 / ebytes;
116911e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116921e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
116931e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
116941e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                n = Bits32 (opcode, 19, 16);
116951e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                m = Bits32 (opcode, 3, 0);
116961e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
116971e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // wback = (m != 15); register_index = (m != 15 && m != 13);
116981e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                wback = (m != 15);
116991e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                register_index = ((m != 15) && (m != 13));
117001e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117011e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
117021e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                if ((d + regs) > 32)
117031e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    return false;
117041e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117051e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                if (n == 15)
117061e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    return false;
117071e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117081e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            }
117091e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                break;
117101e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117111e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            default:
117121e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                return false;
117131e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        }
117141e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
11715c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
11716c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
117171e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117181e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
117191e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        if (!success)
117201e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            return false;
117211e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117221e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
117231e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        addr_t address = Rn;
117241e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        if ((address % alignment) != 0)
117251e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            return false;
117261e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117271e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        EmulateInstruction::Context context;
117281e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
117291e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        if (wback)
117301e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        {
117311e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            uint32_t Rm = ReadCoreReg (m, &success);
117321e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            if (!success)
117331e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                return false;
117341e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117351e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            uint32_t offset;
117361e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            if (register_index)
117371e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                offset = Rm;
117381e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            else
117391e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                offset = 8 * regs;
117401e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117411e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            context.type = eContextAdjustBaseRegister;
117421e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            context.SetRegisterPlusOffset (base_reg, offset);
117431e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117441e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
117451e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                return false;
117461e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        }
117471e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
11748c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
117491e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        context.type = eContextRegisterStore;
117501e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        // for r = 0 to regs-1
117517e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t r = 0; r < regs; ++r)
117521e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        {
11753c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton            GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
117541e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
117551e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            if (!success)
117561e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                return false;
117571e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117581e542e30870bbced43d8438d125979dc9522ec07Caroline Tice             // for e = 0 to elements-1
117597e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs            for (uint32_t e = 0; e < elements; ++e)
117601e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            {
117611e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
117627b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
117631e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117641e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
117651e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                if (!MemUWrite (context, address, word, ebytes))
117661e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                    return false;
117671e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117681e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                // address = address + ebytes;
117691e542e30870bbced43d8438d125979dc9522ec07Caroline Tice                address = address + ebytes;
117701e542e30870bbced43d8438d125979dc9522ec07Caroline Tice            }
117711e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        }
117721e542e30870bbced43d8438d125979dc9522ec07Caroline Tice    }
117731e542e30870bbced43d8438d125979dc9522ec07Caroline Tice    return true;
117741e542e30870bbced43d8438d125979dc9522ec07Caroline Tice}
117751e542e30870bbced43d8438d125979dc9522ec07Caroline Tice
117767b880943399074cc7de69aa02e0da426f52e274eCaroline Tice// A8.6.392 VST1 (single element from one lane)
117777b880943399074cc7de69aa02e0da426f52e274eCaroline Tice// This instruction stores one element to memory from one element of a register.
117787b880943399074cc7de69aa02e0da426f52e274eCaroline Ticebool
117797b880943399074cc7de69aa02e0da426f52e274eCaroline TiceEmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
117807b880943399074cc7de69aa02e0da426f52e274eCaroline Tice{
117817b880943399074cc7de69aa02e0da426f52e274eCaroline Tice#if 0
117827b880943399074cc7de69aa02e0da426f52e274eCaroline Tice    if ConditionPassed() then
117837b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
117847b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
117857b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
117867b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        MemU[address,ebytes] = Elem[D[d],index,esize];
117877b880943399074cc7de69aa02e0da426f52e274eCaroline Tice#endif
117887b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
117897b880943399074cc7de69aa02e0da426f52e274eCaroline Tice    bool success = false;
117907b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
117917b880943399074cc7de69aa02e0da426f52e274eCaroline Tice    if (ConditionPassed (opcode))
117927b880943399074cc7de69aa02e0da426f52e274eCaroline Tice    {
117937b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t ebytes;
117947b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t esize;
117957b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t index;
117967b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t alignment;
117977b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t d;
117987b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t n;
117997b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t m;
118007b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        bool wback;
118017b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        bool register_index;
118027b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118037b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        switch (encoding)
118047b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        {
118057b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            case eEncodingT1:
118067b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            case eEncodingA1:
118077b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            {
118087b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                uint32_t size = Bits32 (opcode, 11, 10);
118097b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                uint32_t index_align = Bits32 (opcode, 7, 4);
118107b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
11811061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // if size == �11� then UNDEFINED;
118127b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                if (size == 3)
118137b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    return false;
118147b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118157b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                // case size of
11816061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                if (size == 0) // when �00�
118177b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                {
11818061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<0> != �0� then UNDEFINED;
118197b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    if (BitIsClear (index_align, 0))
118207b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        return false;
118217b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
118227b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    ebytes = 1;
118237b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    esize = 8;
118247b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    index = Bits32 (index_align, 3, 1);
118257b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    alignment = 1;
118267b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                }
11827061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (size == 1) // when �01�
118287b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                {
11829061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<1> != �0� then UNDEFINED;
118307b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    if (BitIsClear (index_align, 1))
118317b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        return false;
118327b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118337b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
118347b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    ebytes = 2;
118357b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    esize = 16;
118367b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    index = Bits32 (index_align, 3, 2);
118377b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
11838061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // alignment = if index_align<0> == �0� then 1 else 2;
118397b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    if (BitIsClear (index_align, 0))
118407b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        alignment = 1;
118417b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    else
118427b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        alignment = 2;
118437b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                }
11844061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                else if (size == 2) // when �10�
118457b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                {
11846061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<2> != �0� then UNDEFINED;
118477b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    if (BitIsClear (index_align, 2))
118487b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        return false;
118497b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
11850061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
118517b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
118527b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        return false;
118537b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118547b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
118557b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    ebytes = 4;
118567b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    esize = 32;
118577b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    index = Bit32 (index_align, 3);
118587b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
11859061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                    // alignment = if index_align<1:0> == �00� then 1 else 4;
118607b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    if (Bits32 (index_align, 1, 0) == 0)
118617b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        alignment = 1;
118627b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    else
118637b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                        alignment = 4;
118647b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                }
118654a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                else
118664a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                {
118674a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                    return false;
118684a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton                }
118697b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
118707b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
118717b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                n = Bits32 (opcode, 19, 16);
118727b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                m = Bits32 (opcode, 3, 0);
118737b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118747b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
118757b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                wback = (m != 15);
118767b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                register_index = ((m != 15) && (m != 13));
118777b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118787b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                if (n == 15)
118797b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                    return false;
118807b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            }
118817b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                break;
118827b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118837b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            default:
118847b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                return false;
118857b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        }
118867b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
11887c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
11888c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
118897b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118907b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
118917b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        if (!success)
118927b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            return false;
118937b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118947b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
118957b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        addr_t address = Rn;
118967b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        if ((address % alignment) != 0)
118977b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            return false;
118987b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
118997b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        EmulateInstruction::Context context;
119007b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
119017b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        if (wback)
119027b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        {
119037b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            uint32_t Rm = ReadCoreReg (m, &success);
119047b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            if (!success)
119057b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                return false;
119067b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119077b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            uint32_t offset;
119087b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            if (register_index)
119097b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                offset = Rm;
119107b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            else
119117b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                offset = ebytes;
119127b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119137b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            context.type = eContextAdjustBaseRegister;
119147b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            context.SetRegisterPlusOffset (base_reg, offset);
119157b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119167b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
119177b880943399074cc7de69aa02e0da426f52e274eCaroline Tice                return false;
119187b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        }
119197b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119207b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        // MemU[address,ebytes] = Elem[D[d],index,esize];
119217b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
119227b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        if (!success)
119237b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            return false;
119247b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119257b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
119267b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
11927c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo data_reg;
11928c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
119297b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        context.type = eContextRegisterStore;
119307b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
119317b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119327b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        if (!MemUWrite (context, address, word, ebytes))
119337b880943399074cc7de69aa02e0da426f52e274eCaroline Tice            return false;
119347b880943399074cc7de69aa02e0da426f52e274eCaroline Tice    }
119357b880943399074cc7de69aa02e0da426f52e274eCaroline Tice    return true;
119367b880943399074cc7de69aa02e0da426f52e274eCaroline Tice}
119377b880943399074cc7de69aa02e0da426f52e274eCaroline Tice
119388d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice// A8.6.309 VLD1 (single element to all lanes)
119398d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline Tice// This instruction loads one element from memory into every element of one or two vectors.
1194093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Ticebool
119418d24b4a3a3351a0db1dabfaf26bdf2eae16b1775Caroline TiceEmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
1194293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice{
1194393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice#if 0
1194493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice    if ConditionPassed() then
1194593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
1194693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
1194793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
1194893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        replicated_element = Replicate(MemU[address,ebytes], elements);
1194993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        for r = 0 to regs-1
1195093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            D[d+r] = replicated_element;
1195193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice#endif
1195293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1195393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice    bool success = false;
1195493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1195593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice    if (ConditionPassed (opcode))
1195693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice    {
1195793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t ebytes;
1195893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t elements;
1195993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t regs;
1196093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t alignment;
1196193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t d;
1196293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t n;
1196393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t m;
1196493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        bool wback;
1196593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        bool register_index;
1196693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1196793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        switch (encoding)
1196893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        {
1196993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            case eEncodingT1:
1197093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            case eEncodingA1:
1197193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            {
11972061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
1197393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                uint32_t size = Bits32 (opcode, 7, 6);
1197493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
1197593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    return false;
1197693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
11977061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
1197893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                ebytes = 1 << size;
1197993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                elements = 8 / ebytes;
1198093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                if (BitIsClear (opcode, 5))
1198193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    regs = 1;
1198293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                else
1198393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    regs = 2;
1198493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
11985061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                //alignment = if a == �0� then 1 else ebytes;
1198693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                if (BitIsClear (opcode, 4))
1198793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    alignment = 1;
1198893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                else
1198993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    alignment = ebytes;
1199093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1199193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
1199293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
1199393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                n = Bits32 (opcode, 19, 16);
1199493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                m = Bits32 (opcode, 3, 0);
1199593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1199693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                //wback = (m != 15); register_index = (m != 15 && m != 13);
1199793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                wback = (m != 15);
1199893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                register_index = ((m != 15) && (m != 13));
1199993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1200093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
1200193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                if ((d + regs) > 32)
1200293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    return false;
1200393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1200493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                if (n == 15)
1200593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                    return false;
1200693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            }
120076ac9e54dfd1d3e4be4326e0f1740e6a5971c4759Johnny Chen            break;
1200893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1200993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            default:
120106ac9e54dfd1d3e4be4326e0f1740e6a5971c4759Johnny Chen                return false;
1201193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        }
1201293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
12013c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        RegisterInfo base_reg;
12014c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
1201593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1201693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
1201793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        if (!success)
1201893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            return false;
1201993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1202093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
1202193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        addr_t address = Rn;
1202293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        if ((address % alignment) != 0)
1202393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            return false;
1202493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1202593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        EmulateInstruction::Context context;
1202693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
1202793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        if (wback)
1202893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        {
1202993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            uint32_t Rm = ReadCoreReg (m, &success);
1203093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            if (!success)
1203193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                return false;
1203293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1203393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            uint32_t offset;
1203493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            if (register_index)
1203593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                offset = Rm;
1203693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            else
1203793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                offset = ebytes;
1203893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1203993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            context.type = eContextAdjustBaseRegister;
1204093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            context.SetRegisterPlusOffset (base_reg, offset);
1204193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1204293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
1204393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                return false;
1204493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        }
1204593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1204693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        // replicated_element = Replicate(MemU[address,ebytes], elements);
1204793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1204893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        context.type = eContextRegisterLoad;
1204993767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint64_t word = MemURead (context, address, ebytes, 0, &success);
1205093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        if (!success)
1205193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            return false;
1205293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1205365f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen        uint64_t replicated_element = 0;
1205493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        uint32_t esize = ebytes * 8;
120557e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t e = 0; e < elements; ++e)
1205693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
1205793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
1205893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        // for r = 0 to regs-1
120597e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs        for (uint32_t r = 0; r < regs; ++r)
1206093767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        {
1206193767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            // D[d+r] = replicated_element;
1206293767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
1206393767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice                return false;
1206493767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        }
1206593767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice    }
1206693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice    return true;
1206793767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice}
1206893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice
120691f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice// B6.2.13 SUBS PC, LR and related instructions
120701f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
120711f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
120721f954f59df9ce7bf58d0353ab0949656561210d4Caroline Ticebool
120731f954f59df9ce7bf58d0353ab0949656561210d4Caroline TiceEmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
120741f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice{
120751f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice#if 0
120761f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice    if ConditionPassed() then
120771f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        EncodingSpecificOperations();
120781f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        if CurrentInstrSet() == InstrSet_ThumbEE then
120791f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            UNPREDICTABLE;
120801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
120811f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        case opcode of
12082061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0000� result = R[n] AND operand2; // AND
12083061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0001result = R[n] EOR operand2; // EOR
12084061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12085061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12086061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12087061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12088061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12089061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12090061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when1100result = R[n] OR operand2; // ORR
12091061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when1101result = operand2; // MOV
12092061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when1110result = R[n] AND NOT(operand2); // BIC
12093061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            when1111result = NOT(operand2); // MVN
12094061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        CPSRWriteByInstr(SPSR[], �1111�, TRUE);
120951f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        BranchWritePC(result);
120961f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice#endif
120971f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
120981f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice    bool success = false;
120991f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice    if (ConditionPassed (opcode))
121011f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice    {
121021f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t n;
121031f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t m;
121041f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t imm32;
121051f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        bool register_form;
121061f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        ARM_ShifterType shift_t;
121071f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t shift_n;
121081f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t code;
121091f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121101f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        switch (encoding)
121111f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        {
121121f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            case eEncodingT1:
121131f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12114061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
121151f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                n = 14;
121161f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                imm32 = Bits32 (opcode, 7, 0);
121171f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                register_form = false;
121181f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                code = 2;
121191f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121201f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
121211f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                if (InITBlock() && !LastInITBlock())
121221f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                    return false;
121231f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121241f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121251f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121261f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            case eEncodingA1:
121271f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
121281f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                n = Bits32 (opcode, 19, 16);
121291f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                imm32 = ARMExpandImm (opcode);
121301f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                register_form = false;
121311f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                code = Bits32 (opcode, 24, 21);
121321f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121331f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121341f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121351f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            case eEncodingA2:
121361f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
121371f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                n = Bits32 (opcode, 19, 16);
121381f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                m = Bits32 (opcode, 3, 0);
121391f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                register_form = true;
121401f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121411f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
121421f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                shift_n = DecodeImmShiftARM (opcode, shift_t);
121431f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121441f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121451f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121461f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            default:
121471f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return false;
121481f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        }
121491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121501f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
121511f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t operand2;
121521f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        if (register_form)
121531f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        {
121541f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            uint32_t Rm = ReadCoreReg (m, &success);
121551f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            if (!success)
121561f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return false;
121571f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12158a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12159a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen            if (!success)
12160a4438a727670dc08eafd86f2bc8f91fc397f1333Johnny Chen                return false;
121611f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        }
121621f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        else
121631f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        {
121641f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            operand2 = imm32;
121651f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        }
121661f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121671f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t Rn = ReadCoreReg (n, &success);
121681f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        if (!success)
121691f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return false;
121701f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121711f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        AddWithCarryResult result;
121721f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
121731f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        // case opcode of
121741f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        switch (code)
121751f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        {
12176061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 0: // when �0000�
121771f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // result = R[n] AND operand2; // AND
121781f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result.result = Rn & operand2;
121791f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121801f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12181061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 1: // when �0001�
121821f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // result = R[n] EOR operand2; // EOR
121831f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result.result = Rn ^ operand2;
121841f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121851f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12186061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 2: // when �0010�
12187061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
121881f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result = AddWithCarry (Rn, ~(operand2), 1);
121891f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121901f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12191061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 3: // when �0011�
12192061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
121931f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result = AddWithCarry (~(Rn), operand2, 1);
121941f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
121951f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12196061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 4: // when �0100�
12197061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
121981f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result = AddWithCarry (Rn, operand2, 0);
121991f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122001f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12201061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 5: // when �0101�
122021f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
122031f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result = AddWithCarry (Rn, operand2, APSR_C);
122041f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122051f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12206061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 6: // when �0110�
122071f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
122081f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result = AddWithCarry (Rn, ~(operand2), APSR_C);
122091f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122101f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12211061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 7: // when �0111�
122121f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
122131f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result = AddWithCarry (~(Rn), operand2, APSR_C);
122141f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122151f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12216061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 10: // when �1100�
122171f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // result = R[n] OR operand2; // ORR
122181f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result.result = Rn | operand2;
122191f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122201f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12221061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 11: // when �1101�
122221f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // result = operand2; // MOV
122231f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result.result = operand2;
122241f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122251f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12226061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 12: // when �1110�
122271f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // result = R[n] AND NOT(operand2); // BIC
122281f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result.result = Rn & ~(operand2);
122291f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122301f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
12231061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton            case 15: // when �1111�
122321f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                // result = NOT(operand2); // MVN
122331f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                result.result = ~(operand2);
122341f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                break;
122351f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
122361f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            default:
122371f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice                return false;
122381f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        }
12239061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton        // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
122401f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
122411f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
122421f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        // the best.
122431f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
122441f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        if (!success)
122451f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice            return false;
122461f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
122471f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        CPSRWriteByInstr (spsr, 15, true);
122481f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
122491f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        // BranchWritePC(result);
122501f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        EmulateInstruction::Context context;
122511f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        context.type = eContextAdjustPC;
122521f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        context.SetImmediate (result.result);
122531f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
122541f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        BranchWritePC (context, result.result);
122551f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice    }
122561f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice    return true;
122571f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice}
122581f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice
122592b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode*
12260888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
1226164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
122622b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static ARMOpcode
122632b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    g_arm_opcodes[] =
122642b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
122652b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
122662b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Prologue instructions
122672b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
122682b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122692b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push register(s)
122704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
122714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
122722b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122732b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // set r7 to point to a stack offset
122744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
122754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12276e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // copy the stack pointer to ip
122774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
122784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
122794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
122802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // adjust the stack pointer
122824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
122834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
122842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122852b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push one register
122862b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
122874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
122882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // vector push consecutive extension register(s)
122904f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
122914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
122922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
12294587a0a4e5341bac8a8936b84fc73d6a7e8ada46fJohnny Chen        // Epilogue instructions
122952b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
122962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
122974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
122984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
122994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
123004f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12301b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
12302b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
12303b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        // Supervisor Call (previously Software Interrupt)
12304b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
123054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
123063b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
123073b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
123083b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // Branch instructions
123093b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
123104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12311383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
123124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
123134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
123144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12315ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        // for example, "bx lr"
123164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
1231759e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        // bxj
123184f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12319b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
12320b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
1232128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        // Data-processing instructions
1232228070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        //----------------------------------------------------------------------
12323157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (immediate)
123244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12325157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (register)
123264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
123278fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        // add (immediate)
123284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
123298fa2059234b17e9c377eea49b01f0ea084f66843Johnny Chen        // add (register)
123304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12331c08ed3840e47b2e26ddffe0154b21840c80c91dfCaroline Tice        // add (register-shifted register)
123320fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12333a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        // adr
123344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
123354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12336e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (immediate)
123374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12338e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (register)
123394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12340b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // bic (immediate)
123414f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12342b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // bic (register)
123434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
123442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (immediate)
123454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
123462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (register)
123474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
123487c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (immediate)
123494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
123507c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (register)
123514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12352ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // rsb (immediate)
123534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12354ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // rsb (register)
123554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
1235690e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        // rsc (immediate)
123574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
1235890e607bfccc74572e8422ea85d20f10db6f936b9Johnny Chen        // rsc (register)
123594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
123609b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        // sbc (immediate)
123614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
123629b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        // sbc (register)
123634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
1236415a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // sub (immediate, ARM)
123654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12366c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        // sub (sp minus immediate)
123674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
123684cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        // sub (register)
123694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
123702115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (immediate)
123714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
123722115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (register)
123734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12374de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (immediate)
123754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12376de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (register)
123774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12378de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
1237989c6d5830f0584ed2f984e2d557ded17add7f61bCaroline Tice        // mov (immediate)
123804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
123814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
1238201d61570a57c96b3dbca0d89bf3039fe7fc99870Johnny Chen        // mov (register)
123834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12384d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (immediate)
123854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12386d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (register)
123874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
123883847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen        // cmn (immediate)
123894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
123903847dadf9d633ead9e7697cb636f0e0210576731Johnny Chen        // cmn (register)
123914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
1239234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (immediate)
123934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
1239434075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (register)
123954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
1239682f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // asr (immediate)
123974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
123982ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // asr (register)
123994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
124002ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (immediate)
124014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
124022ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (register)
124034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
124042ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (immediate)
124054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
124062ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (register)
124074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12408eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // rrx is a special case encoding of ror (immediate)
124094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12410eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (immediate)
124114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12412eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (register)
124134f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
124145c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // mul
124154f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
124166b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
124176b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        // subs pc, lr and related instructions
124181f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
124191f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
1242028070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen
1242128070c30cc87cc9679bb35bc11c42d0cc6ed4b0eJohnny Chen        //----------------------------------------------------------------------
12422b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        // Load instructions
12423b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
124244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
124254f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
124264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
124274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
124284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
124294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
124304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
124314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
124324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
124334f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
124344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
124354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
124364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
124374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
124384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
124394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
124404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
124414f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
124429121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
124439121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
124449121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
124459121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12446b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12447b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
1244893767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12449fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
12450fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
12451fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // Store instructions
12452fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
124534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
124544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
124554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
124564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
124574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
124584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
124594f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
124604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
124614f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
124620fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
124634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
124641e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
124651e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
124661e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
124671e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
124681e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
124697b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
124706bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
124716bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        //----------------------------------------------------------------------
124726bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        // Other instructions
124736bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        //----------------------------------------------------------------------
124744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
124754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
124764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
124774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
124784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
124791511f50f447c36af933d10910bc3d6cd1f41bfd3Caroline Tice
124802b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    };
124812b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
124822b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
124832b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    for (size_t i=0; i<k_num_arm_opcodes; ++i)
124842b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
12485888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12486888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            (g_arm_opcodes[i].variants & arm_isa) != 0)
124872b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            return &g_arm_opcodes[i];
124882b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    }
124892b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    return NULL;
124902b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
124912b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
124922b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
124932b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg ClaytonEmulateInstructionARM::ARMOpcode*
12494888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12495347320d16d98cffaadf3f888569100c43b241068Johnny Chen{
124962b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
124972b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    static ARMOpcode
124982b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    g_thumb_opcodes[] =
124992b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
125002b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
125012b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Prologue instructions
125022b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
125032b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
125042b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // push register(s)
125054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
125064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
125074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
125082b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
125092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // set r7 to point to a stack offset
125104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12511e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // copy the stack pointer to r7
125124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12513e7cf4206fd3fa57067a9612118250bbfb88a4e68Johnny Chen        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
125144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
125152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
12516864a8e86b9e89d0f52b5020ace524eefebc9b9afJohnny Chen        // PC-relative load into register (see also EmulateADDSPRm)
125174f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
125182b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
125192b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // adjust the stack pointer
125204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
125214f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
125224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
125234f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
125244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
125252b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
125262b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // vector push consecutive extension register(s)
125274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
125284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
125292b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
125302b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
125312b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        // Epilogue instructions
125322b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton        //----------------------------------------------------------------------
125332b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
125344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
125354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
125364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
125374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
125384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
125394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
125404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12541b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
12542b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
12543b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        // Supervisor Call (previously Software Interrupt)
12544b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen        //----------------------------------------------------------------------
125454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12546c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
12547c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        //----------------------------------------------------------------------
12548c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        // If Then makes up to four following instructions conditional.
12549c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        //----------------------------------------------------------------------
1255004d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        // The next 5 opcode _must_ come before the if then instruction
1255104d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
1255204d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
1255304d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
1255404d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
1255504d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
1255604d397c5e251eaa5f520dbe6381d2a82303350e1Greg Clayton        { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
125573b620b38cd170c20ea607585021ab2ab50286943Johnny Chen
125583b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
125593b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // Branch instructions
125603b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        //----------------------------------------------------------------------
125613b620b38cd170c20ea607585021ab2ab50286943Johnny Chen        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
125624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
125634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
125644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
125654f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12566383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // J1 == J2 == 1
125674f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12568383d629938986b4ae4867f08505be8a9147c1308Johnny Chen        // J1 == J2 == 1
125694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
125704f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12571ab3b3514b639d2cab1cd6c71c317e12059717a17Johnny Chen        // for example, "bx lr"
125724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
1257359e6ab70eb0a623fc667f7db9b27007e13b315e2Johnny Chen        // bxj
125744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
1257553ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        // compare and branch
125764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
1257760299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        // table branch byte
125784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
1257960299ec172c9bbeab4e1bbffad513d75cd1741deJohnny Chen        // table branch halfword
125804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12581b77be414a1a4b74827f30e5944a58d4af0445ff4Johnny Chen
12582b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
1258326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Data-processing instructions
1258426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        //----------------------------------------------------------------------
12585157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (immediate)
125864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12587157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // adc (register)
125884f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
125894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12590157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        // add (register)
125914f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
1259226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
125934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12594a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        // adr
125954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
125964f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
125974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12598e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (immediate)
125994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12600e97c0d5ea7b614b1fb257f63591e122e5651227cJohnny Chen        // and (register)
126014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
126024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12603b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // bic (immediate)
126044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12605b9f02cfcd7d85e74981bf7790dce15d9bd1d4df6Johnny Chen        // bic (register)
126064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
126074f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
126082115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (immediate)
126094f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
126102115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // eor (register)
126114f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
126124f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
126137c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (immediate)
126144f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
126157c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // orr (register)
126164f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
126174f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12618ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // rsb (immediate)
126194f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
126204f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12621ed32e7cdec9c0c88ad40c9ed3d05e7604599a563Johnny Chen        // rsb (register)
126224f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
126239b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        // sbc (immediate)
126244f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
126259b381775c532270fd07a90aa1a98750546a768b7Johnny Chen        // sbc (register)
126264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
126274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12628dcc11b3b8882b3522244a25d2915c9086b44e596Caroline Tice        // add (immediate, Thumb)
126294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
126304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
126314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
126324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
1263315a7a6b9b624e5b8a2b058befc4e04aae72ff9c0Johnny Chen        // sub (immediate, Thumb)
126344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
126354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
126364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
126374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12638c9e747f4efa320e366498f02bb9dd791cf86623bJohnny Chen        // sub (sp minus immediate)
126394f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
126404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
126414cccd53eba9c0ab2b3a4cf4aca42a2669d8834f4Caroline Tice        // sub (register)
126424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
126434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
126442115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (immediate)
126454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
126462115b4131b0e427341959fb4007e0173bf71778dJohnny Chen        // teq (register)
126474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12648de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (immediate)
126494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12650de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen        // tst (register)
126514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
126524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12653de3cce3aa8e10c9e328e15b9210069b77f840b70Johnny Chen
126547c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen
12655338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        // move from high register to high register
126564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12657338bf54a49633d90f3c5e808847470901f25dee9Johnny Chen        // move from low register to low register
126584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
126597c5234db18ead0935e884429b3cace95b3a9dce4Johnny Chen        // mov{s}<c>.w <Rd>, <Rm>
126604f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12661357c30f55eeeca5df8434831c8963ef8fc109227Johnny Chen        // move immediate
126624f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
126634f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
126644f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12665d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (immediate)
126664f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12667d642a6ad6b8e3822485a8a08fbbfa8b60a4e97f2Johnny Chen        // mvn (register)
126684f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
126694f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
1267034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmn (immediate)
126714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
1267234075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmn (register)
126734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
126744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
1267534075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (immediate)
126764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
126774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
1267834075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (register) (Rn and Rm both from r0-r7)
126794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
1268034075cb14fb56cb350e71cc696179ab0f2744423Johnny Chen        // cmp (register) (Rn and Rm not both from r0-r7)
126814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
1268282f16aa9f19678ffa20b92a8df926e933940d34dJohnny Chen        // asr (immediate)
126834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
126844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12685e7f8953988d593882971e4134f8423f4af1cffaaJohnny Chen        // asr (register)
126864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
126874f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
126882ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (immediate)
126894f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
126904f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
126912ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsl (register)
126924f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
126934f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
126942ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (immediate)
126954f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
126964f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
126972ee35bcf1670c112b004736bf8beb672629e3e93Johnny Chen        // lsr (register)
126984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
126994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12700eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // rrx is a special case encoding of ror (immediate)
127014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12702eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (immediate)
127034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12704eeab485b0c1197bc4f483a9fdd7d2489703cb5abJohnny Chen        // ror (register)
127054f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
127064f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
127075c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // mul
127084f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
127095c1e2edcc5230fbf0995efcc32e9c0548a97a2d2Caroline Tice        // mul
127104f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
127116b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
127126b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        // subs pc, lr and related instructions
127131f954f59df9ce7bf58d0353ab0949656561210d4Caroline Tice        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12714080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
12715080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        //----------------------------------------------------------------------
12716080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12717080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        // otherwise the wrong instructions will be selected.
12718080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        //----------------------------------------------------------------------
127196bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
12720080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12721080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12722080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
1272326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        //----------------------------------------------------------------------
12724b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        // Load instructions
12725b9f76c33ab97dcef2e9c1dbc471097edd6b98a86Caroline Tice        //----------------------------------------------------------------------
127264f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
127274f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
127284f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
127294f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
127304f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
127314f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
127324f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12733baf1f648fd0eb9295d8e61567d49d47fb9c28e19Caroline Tice                  // Thumb2 PC-relative load into register
127344f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
127354f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
127364f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
127374f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
127384f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
127390fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
127404f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
127414f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
127424f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
127434f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
127444f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
127454f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
127464f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
127474f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
127484f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
127494f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
127504f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
127514f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
127524f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
127534f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
127544f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
127554f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
127564f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
127574f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
127584f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
127590fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
127609121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
127619121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
127629121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
127639121b35e4d2742ce9627bdfeea7cffed123d7bbaCaroline Tice        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12764b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12765b6281b1d94e75876211a589bc9c4e2756feab04eCaroline Tice        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
1276693767b8fceecd605d3e3dc3803b7d51823f17b2fCaroline Tice        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12767fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice
12768fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
12769fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        // Store instructions
12770fa17220ce8b3db56b05317fd5e69c450127f8538Caroline Tice        //----------------------------------------------------------------------
127714f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
127724f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
127734f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
127744f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
127754f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
127764f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
127774f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
127784f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
127794f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
127804f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
127814f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
127824f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
127834f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
127844f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
127854f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
127864f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
127871e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
127881e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
127891e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
127901e542e30870bbced43d8438d125979dc9522ec07Caroline Tice        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
127910a6822658ec5f61f42b6b144345b972a4253995fJason Molenda        { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
127927b880943399074cc7de69aa02e0da426f52e274eCaroline Tice        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
127936bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice
127946bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        //----------------------------------------------------------------------
127956bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        // Other instructions
127966bf65165d269c43dc6cfd227c5f1e287c24b5a41Caroline Tice        //----------------------------------------------------------------------
127974f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
127984f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
127994f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
128004f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
128014f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
128024f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
128034f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
128044f6055840a3d5006a60d54c139b1f8975ed0c638Caroline Tice        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
128052b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    };
128062b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton
128072b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
128082b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
128092b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    {
12810888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12811888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            (g_thumb_opcodes[i].variants & arm_isa) != 0)
128122b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton            return &g_thumb_opcodes[i];
128132b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    }
128142b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton    return NULL;
128152b8e8b0d1ea00d0076ac20568c2ce2a2a1fe0240Greg Clayton}
1281664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1281731e2a388b07f337c1bf61de32a39c154f190c06eGreg Claytonbool
12818395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonEmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
1281931e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton{
12820080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    m_arch = arch;
1282131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    m_arm_isa = 0;
12822940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    const char *arch_cstr = arch.GetArchitectureName ();
12823395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    if (arch_cstr)
12824395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    {
12825395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12826395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12827395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12828395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12829395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12830395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
1283182a17a29a99ceef3353ac669ed44749d6106212cJason Molenda        else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
128321d29a85815ee049b4f30271161c3b494eef41e8cJohnny Chen        else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
128331d29a85815ee049b4f30271161c3b494eef41e8cJohnny Chen        else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12834663067fa1a4992523d771c823368f54979249cf9Greg Clayton        else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12835663067fa1a4992523d771c823368f54979249cf9Greg Clayton        else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12836663067fa1a4992523d771c823368f54979249cf9Greg Clayton        else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12837663067fa1a4992523d771c823368f54979249cf9Greg Clayton        else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
1283831e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    }
1283931e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton    return m_arm_isa != 0;
1284031e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton}
1284131e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton
12842080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Ticebool
12843888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12844080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice{
12845888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12846888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    {
12847888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12848888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            m_opcode_mode = eModeThumb;
12849888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        else
12850888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        {
12851888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            AddressClass addr_class = inst_addr.GetAddressClass();
12852080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
12853888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12854888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                m_opcode_mode = eModeARM;
12855888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            else if (addr_class == eAddressClassCodeAlternateISA)
12856888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                m_opcode_mode = eModeThumb;
12857888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            else
12858888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                return false;
12859888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        }
12860888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if (m_opcode_mode == eModeThumb)
12861888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12862888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        else
12863888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            m_opcode_cpsr = CPSR_MODE_USR;
12864888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return true;
12865888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    }
12866888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    return false;
12867080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice}
1286831e2a388b07f337c1bf61de32a39c154f190c06eGreg Clayton
1286964c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
1287064c8443d255f44267490c8c839f4a9365cf55ea7Greg ClaytonEmulateInstructionARM::ReadInstruction ()
1287164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
1287264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool success = false;
12873b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
1287464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (success)
1287564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
1287664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
1287764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        if (success)
1287864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        {
128799bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            Context read_inst_context;
128809bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            read_inst_context.type = eContextReadOpcode;
128819bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice            read_inst_context.SetNoArgs ();
128829bfe7f219fb47d93c2b866ad5a6342a827d0dbd6Caroline Tice
12883b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            if (m_opcode_cpsr & MASK_CPSR_T)
1288464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
12885b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton                m_opcode_mode = eModeThumb;
12886cc96eb5967d878e8225ce61c645eb47857fbb3f2Caroline Tice                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
1288764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1288864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                if (success)
1288964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                {
128907bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
1289164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    {
128927bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                        m_opcode.SetOpcode16 (thumb_opcode);
1289364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    }
1289464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    else
1289564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    {
128967bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
1289764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                    }
1289864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton                }
1289964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
1290064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            else
1290164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            {
12902b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton                m_opcode_mode = eModeARM;
129037bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
1290464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            }
1290564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
1290664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
1290764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (!success)
1290864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
12909b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton        m_opcode_mode = eModeInvalid;
129103063c95c54ac0303287c34f9f5af7ba7b6b8f0bcGreg Clayton        m_addr = LLDB_INVALID_ADDRESS;
1291164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
1291264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return success;
1291364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
1291464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
12915ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenuint32_t
12916ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::ArchVersion ()
12917ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
12918ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return m_arm_isa;
12919ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
12920ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
1292164c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
12922107e53da8bdca540db8b734ed237688eaeee85c5Greg ClaytonEmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
1292364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
12924888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton   // If we are ignoring conditions, then always return true.
12925888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton   // this allows us to iterate over disassembly code and still
12926888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton   // emulate an instruction even if we don't have all the right
12927888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton   // bits set in the CPSR register...
12928888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (m_ignore_conditions)
12929888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return true;
12930107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton
12931107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton    if (is_conditional)
12932107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        *is_conditional = true;
1293364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
129347bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton    const uint32_t cond = CurrentCond (opcode);
1293564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1293664c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (cond == UINT32_MAX)
1293764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        return false;
1293864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1293964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    bool result = false;
1294064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    switch (UnsignedBits(cond, 3, 1))
1294164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    {
12942080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    case 0:
12943080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		if (m_opcode_cpsr == 0)
12944107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton			result = true;
12945107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12946107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12947080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		break;
12948080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    case 1:
12949107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (m_opcode_cpsr == 0)
12950107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = true;
12951107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12952107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12953080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		break;
12954080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    case 2:
12955107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (m_opcode_cpsr == 0)
12956107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = true;
12957107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12958107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12959080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		break;
12960080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    case 3:
12961107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (m_opcode_cpsr == 0)
12962107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = true;
12963107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12964107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12965080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		break;
12966080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    case 4:
12967107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (m_opcode_cpsr == 0)
12968107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = true;
12969107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12970107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12971080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		break;
1297264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 5:
12973107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (m_opcode_cpsr == 0)
12974107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = true;
12975107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12976080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		{
12977b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12978b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            bool v = (m_opcode_cpsr & MASK_CPSR_V);
1297964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton            result = n == v;
1298064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
1298164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
1298264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 6:
12983107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (m_opcode_cpsr == 0)
12984107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            result = true;
12985107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        else
12986080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice		{
12987b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12988b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12989b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
1299064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        }
1299164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
1299264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    case 7:
12993107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        // Always execute (cond == 0b1110, or the special 0b1111 which gives
12994107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        // opcodes different meanings, but always means execution happpens.
12995107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton        if (is_conditional)
12996107e53da8bdca540db8b734ed237688eaeee85c5Greg Clayton            *is_conditional = false;
1299764c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        result = true;
1299864c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        break;
1299964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    }
1300064c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
1300164c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    if (cond & 1)
1300264c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton        result = !result;
1300364c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton    return result;
1300464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
1300564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
130069ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenuint32_t
130077bc390873f7c1c798c36c8003c4b82597f67c703Greg ClaytonEmulateInstructionARM::CurrentCond (const uint32_t opcode)
130089ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
13009b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    switch (m_opcode_mode)
130109ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
130119ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeInvalid:
130129ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        break;
130139ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
130149ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeARM:
130157bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton        return UnsignedBits(opcode, 31, 28);
130169ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
130179ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    case eModeThumb:
130189ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
130199ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        // 'cond' field of the encoding.
130209ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        {
130217bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            const uint32_t byte_size = m_opcode.GetByteSize();
130227bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            if (byte_size == 2)
130237bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            {
130247bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
130257bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                    return Bits32(opcode, 11, 7);
130267bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            }
130276dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen            else if (byte_size == 4)
130287bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            {
130297bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                if (Bits32(opcode, 31, 27) == 0x1e &&
130307bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                    Bits32(opcode, 15, 14) == 0x02 &&
130317bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                    Bits32(opcode, 12, 12) == 0x00 &&
130327bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                    Bits32(opcode, 25, 22) <= 0x0d)
130337bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                {
130347bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                    return Bits32(opcode, 25, 22);
130357bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton                }
130367bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            }
130376dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen            else
130386dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen                // We have an invalid thumb instruction, let's bail out.
130396dc5a1aaee217d49d91f157390b0de06a0f71681Johnny Chen                break;
130407bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton
130417bc390873f7c1c798c36c8003c4b82597f67c703Greg Clayton            return m_it_session.GetCond();
130429ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        }
130439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
130449ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    return UINT32_MAX;  // Return invalid value
130459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
130469ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
130479ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool
13048098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::InITBlock()
13049098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{
13050098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13051098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen}
13052098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen
13053098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool
13054098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny ChenEmulateInstructionARM::LastInITBlock()
13055098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen{
13056098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13057098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen}
13058098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chen
13059b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool
13060b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::BadMode (uint32_t mode)
13061b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{
13062b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13063b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    switch (mode)
13064b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    {
13065b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 16: return false; // '10000'
13066b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 17: return false; // '10001'
13067b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 18: return false; // '10010'
13068b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 19: return false; // '10011'
13069b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 22: return false; // '10110'
13070b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 23: return false; // '10111'
13071b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 27: return false; // '11011'
13072b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        case 31: return false; // '11111'
13073b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        default: return true;
13074b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    }
13075b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    return true;
13076b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice}
13077b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13078b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticebool
13079b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CurrentModeIsPrivileged ()
13080b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{
13081b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13082b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13083b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if (BadMode (mode))
13084b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        return false;
13085b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13086b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if (mode == 16)
13087888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return false;
13088b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13089b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    return true;
13090b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice}
13091b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13092b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Ticevoid
13093b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline TiceEmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13094b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice{
13095b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    bool privileged = CurrentModeIsPrivileged();
13096b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
1309765f39ed3847cdf09381de6dce8abfa28caa96486Johnny Chen    uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13098b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13099b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if (BitIsSet (bytemask, 3))
13100b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    {
13101b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13102b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (affect_execstate)
13103b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13104b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    }
13105b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13106b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if (BitIsSet (bytemask, 2))
13107b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    {
13108b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13109b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    }
13110b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13111b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if (BitIsSet (bytemask, 1))
13112b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    {
13113b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (affect_execstate)
13114b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13115b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13116b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (privileged)
13117b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13118b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    }
13119b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13120b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    if (BitIsSet (bytemask, 0))
13121b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    {
13122b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (privileged)
13123b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13124b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (affect_execstate)
13125b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13126b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice        if (privileged)
13127b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13128b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice    }
13129b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13130b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    m_opcode_cpsr = tmp_cpsr;
13131b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice}
13132b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13133b27771da2fe3256f4a64729ecec05946c27c1a0aCaroline Tice
13134098ae2d54f9b1613e85ecb5f3d0808f102a97859Johnny Chenbool
131359ee056bb17843e8c757461dbf56c49e8de99a65eJohnny ChenEmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
131369ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
131379ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    addr_t target;
131389ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
13139ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    // Check the current instruction set.
13140ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    if (CurrentInstrSet() == eModeARM)
131419ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffc;
13142ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    else
131439ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffe;
13144ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
131459ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
1314653ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
1314753ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
1314853ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
131499ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
131509ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
131519ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
131529ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chenbool
13153668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
131549ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen{
131559ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    addr_t target;
131560f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
131570f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // we want to record it and issue a WriteRegister callback so the clients
131580f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    // can track the mode changes accordingly.
131590f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    bool cpsr_changed = false;
131609ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
131619ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (BitIsSet(addr, 0))
131629ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
131630f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        if (CurrentInstrSet() != eModeThumb)
131640f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        {
131650f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            SelectInstrSet(eModeThumb);
131660f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            cpsr_changed = true;
131670f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        }
131689ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffe;
13169c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.SetISA (eModeThumb);
131709ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
131719ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    else if (BitIsClear(addr, 1))
131729ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    {
131730f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        if (CurrentInstrSet() != eModeARM)
131740f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        {
131750f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            SelectInstrSet(eModeARM);
131760f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            cpsr_changed = true;
131770f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen        }
131789ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        target = addr & 0xfffffffc;
13179c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton        context.SetISA (eModeARM);
131809ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    }
131819ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    else
131829ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen        return false; // address<1:0> == '10' => UNPREDICTABLE
131839ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen
131840f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    if (cpsr_changed)
131850f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    {
13186558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
131870f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen            return false;
131880f309db3ba3f297599809bac0bbbb13719f1c860Johnny Chen    }
131899ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
1319053ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen        return false;
1319153ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen
1319253ebab7a7bed312c496a49d52b225a01a1a02e89Johnny Chen    return true;
131939ee056bb17843e8c757461dbf56c49e8de99a65eJohnny Chen}
1319464c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton
13195ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13196ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool
13197668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13198ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
13199ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    if (ArchVersion() >= ARMv5T)
13200668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        return BXWritePC(context, addr);
13201ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    else
13202ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        return BranchWritePC((const Context)context, addr);
13203ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
13204ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
1320526863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
1320626863dc1d68712415ed56c9953f6fed79b38e131Johnny Chenbool
13207668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny ChenEmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
1320826863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen{
1320926863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13210668b45124a14cbd03e7b4965b3d86fdbf208d282Johnny Chen        return BXWritePC(context, addr);
1321126863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen    else
1321226863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen        return BranchWritePC((const Context)context, addr);
1321326863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen}
1321426863dc1d68712415ed56c9953f6fed79b38e131Johnny Chen
13215ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::Mode
13216ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::CurrentInstrSet ()
13217ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
13218b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    return m_opcode_mode;
13219ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
13220ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
13221b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13222558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// ReadInstruction() is performed.  This function has a side effect of updating
13223558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen// the m_new_inst_cpsr member variable if necessary.
13224ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chenbool
13225ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny ChenEmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13226ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen{
13227b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    m_new_inst_cpsr = m_opcode_cpsr;
13228ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    switch (arm_or_thumb)
13229ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    {
13230ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    default:
13231ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        return false;
13232b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton    case eModeARM:
13233ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        // Clear the T bit.
13234558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        m_new_inst_cpsr &= ~MASK_CPSR_T;
13235ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        break;
13236b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton    case eModeThumb:
13237ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        // Set the T bit.
13238558133bb1d2d89dd4618259ce27b5c06f3970b48Johnny Chen        m_new_inst_cpsr |= MASK_CPSR_T;
13239ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen        break;
13240ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    }
13241ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen    return true;
13242ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen}
13243ee9b1f7a1b52427f8ac3ae43d8064f10add803b1Johnny Chen
13244ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// This function returns TRUE if the processor currently provides support for
13245ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13246ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13247ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chenbool
13248ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny ChenEmulateInstructionARM::UnalignedSupport()
13249ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen{
13250ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen    return (ArchVersion() >= ARMv7);
13251ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen}
13252ef21b59059720fb14bf169f08c3cc3ffc2c598c8Johnny Chen
13253bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// The main addition and subtraction instructions can produce status information
13254bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// about both unsigned carry and signed overflow conditions.  This status
13255bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen// information can be used to synthesize multi-word additions and subtractions.
13256bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarryResult
13257bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny ChenEmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13258bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen{
13259bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint32_t result;
13260bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint8_t carry_out;
13261bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint8_t overflow;
13262bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
13263bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    uint64_t unsigned_sum = x + y + carry_in;
13264bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13265bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
13266bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    result = UnsignedBits(unsigned_sum, 31, 0);
132670fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice//    carry_out = (result == unsigned_sum ? 0 : 1);
13268bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    overflow = ((int32_t)result == signed_sum ? 0 : 1);
132690fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice
132700fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    if (carry_in)
13271523c554292bc09fd8519379d628b5e9090acbd36Caroline Tice        carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
132720fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    else
132730fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13274bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
13275bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    AddWithCarryResult res = { result, carry_out, overflow };
13276bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen    return res;
13277bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen}
13278bf6ad173895183797cbd0ebd18710b2364a2c4c8Johnny Chen
13279157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chenuint32_t
13280e39f22d1a369866808b8739c3cec15063d806833Johnny ChenEmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13281157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen{
13282e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t reg_kind, reg_num;
13283e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    switch (num)
13284157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    {
13285e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    case SP_REG:
13286e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_kind = eRegisterKindGeneric;
13287e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_num  = LLDB_REGNUM_GENERIC_SP;
13288e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
13289e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    case LR_REG:
13290e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_kind = eRegisterKindGeneric;
13291e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_num  = LLDB_REGNUM_GENERIC_RA;
13292e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
13293e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    case PC_REG:
13294e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_kind = eRegisterKindGeneric;
13295e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        reg_num  = LLDB_REGNUM_GENERIC_PC;
13296e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
13297e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    default:
132984fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton        if (num < SP_REG)
13299e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        {
13300e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            reg_kind = eRegisterKindDWARF;
13301e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            reg_num  = dwarf_r0 + num;
13302e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        }
13303157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen        else
13304e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        {
13305e1f47bb8c6221abf3a2fe1571b09f208d71d025eGreg Clayton            //assert(0 && "Invalid register number");
13306e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            *success = false;
133074fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton            return UINT32_MAX;
13308e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        }
13309e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        break;
13310e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    }
13311e39f22d1a369866808b8739c3cec15063d806833Johnny Chen
13312e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // Read our register.
13313e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13314e39f22d1a369866808b8739c3cec15063d806833Johnny Chen
13315e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // When executing an ARM instruction , PC reads as the address of the current
13316e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // instruction plus 8.
13317e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // When executing a Thumb instruction , PC reads as the address of the current
13318e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    // instruction plus 4.
13319e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    if (num == 15)
13320e39f22d1a369866808b8739c3cec15063d806833Johnny Chen    {
13321e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        if (CurrentInstrSet() == eModeARM)
13322157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen            val += 8;
13323e39f22d1a369866808b8739c3cec15063d806833Johnny Chen        else
13324e39f22d1a369866808b8739c3cec15063d806833Johnny Chen            val += 4;
13325157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    }
13326157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
13327157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen    return val;
13328157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen}
13329157b959b101cbdddb81a690d00ff0697540d83e7Johnny Chen
13330ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// Write the result to the ARM core register Rd, and optionally update the
13331ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// condition flags based on the result.
13332ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
13333ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// This helper method tries to encapsulate the following pseudocode from the
13334ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// ARM Architecture Reference Manual:
13335ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
13336ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// if d == 15 then         // Can only occur for encoding A1
13337ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     ALUWritePC(result); // setflags is always FALSE here
13338ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// else
13339ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     R[d] = result;
13340ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//     if setflags then
13341ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.N = result<31>;
13342ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.Z = IsZeroBit(result);
13343ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         APSR.C = carry;
13344ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//         // APSR.V unchanged
13345ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen//
13346ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// In the above case, the API client does not pass in the overflow arg, which
13347ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen// defaults to ~0u.
13348ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chenbool
1334910530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
1335010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t result,
1335110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t Rd,
1335210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  bool setflags,
1335310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t carry,
1335410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                                  const uint32_t overflow)
13355ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen{
13356ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    if (Rd == 15)
13357ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    {
13358ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (!ALUWritePC (context, result))
13359ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
13360ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    }
13361ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    else
13362ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    {
13363a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        uint32_t reg_kind, reg_num;
13364a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        switch (Rd)
13365a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        {
13366a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case SP_REG:
13367a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            reg_kind = eRegisterKindGeneric;
13368a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            reg_num  = LLDB_REGNUM_GENERIC_SP;
13369a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            break;
13370a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        case LR_REG:
13371a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            reg_kind = eRegisterKindGeneric;
13372a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            reg_num  = LLDB_REGNUM_GENERIC_RA;
13373a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            break;
13374a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        default:
13375a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            reg_kind = eRegisterKindDWARF;
13376a695f958db37c102d480a9c0780abec262ba8332Johnny Chen            reg_num  = dwarf_r0 + Rd;
13377a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        }
13378a695f958db37c102d480a9c0780abec262ba8332Johnny Chen        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13379ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen            return false;
13380ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen        if (setflags)
1338110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen            return WriteFlags (context, result, carry, overflow);
1338210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    }
1338310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    return true;
1338410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen}
1338510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen
1338610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// This helper method tries to encapsulate the following pseudocode from the
1338710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// ARM Architecture Reference Manual:
1338810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen//
1338910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.N = result<31>;
1339010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.Z = IsZeroBit(result);
1339110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.C = carry;
1339210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// APSR.V = overflow
1339310530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen//
1339410530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// Default arguments can be specified for carry and overflow parameters, which means
1339510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen// not to update the respective flags.
1339610530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chenbool
1339710530c2f7bc5030f59563fb877510a218c9cea8fJohnny ChenEmulateInstructionARM::WriteFlags (Context &context,
1339810530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t result,
1339910530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t carry,
1340010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen                                   const uint32_t overflow)
1340110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen{
13402b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    m_new_inst_cpsr = m_opcode_cpsr;
1340324348847b93337ad548032e046c71f37e647da26Johnny Chen    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
1340424348847b93337ad548032e046c71f37e647da26Johnny Chen    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1340510530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (carry != ~0u)
1340624348847b93337ad548032e046c71f37e647da26Johnny Chen        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
1340710530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    if (overflow != ~0u)
1340824348847b93337ad548032e046c71f37e647da26Johnny Chen        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13409b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    if (m_new_inst_cpsr != m_opcode_cpsr)
1341010530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen    {
1341110530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1341210530c2f7bc5030f59563fb877510a218c9cea8fJohnny Chen            return false;
13413ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    }
13414ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen    return true;
13415ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen}
13416ca67d1c9572ad3890aa73863969a4b664f7781bcJohnny Chen
1341764c8443d255f44267490c8c839f4a9365cf55ea7Greg Claytonbool
13418888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonEmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
1341964c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton{
13420c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen    // Advance the ITSTATE bits to their values for the next instruction.
13421b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13422c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen        m_it_session.ITAdvance();
13423c315f860b343cf4a143f43c7d570d151989abb46Johnny Chen
13424888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    ARMOpcode *opcode_data = NULL;
13425080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
13426080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    if (m_opcode_mode == eModeThumb)
13427888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13428080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    else if (m_opcode_mode == eModeARM)
13429888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13430080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
13431888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (opcode_data == NULL)
13432080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice        return false;
13433080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
13434888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13435888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13436888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
13437888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    bool success = false;
13438888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13439080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    {
13440888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13441061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                                                dwarf_cpsr,
13442061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                                                0,
13443061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton                                                &success);
13444080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice    }
13445888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
13446888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    // Only return false if we are unable to read the CPSR if we care about conditions
13447888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (success == false && m_ignore_conditions == false)
13448888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return false;
13449080bf61255afcffd7ccfe0402d3715f77f6627b9Caroline Tice
13450888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    uint32_t orig_pc_value = 0;
13451888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (auto_advance_pc)
134520fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    {
13453888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13454888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if (!success)
13455888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            return false;
134560fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    }
134570fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice
13458888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    // Call the Emulate... function.
13459888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
134600fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    if (!success)
134610fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice        return false;
134620fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice
13463888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    if (auto_advance_pc)
134640fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    {
13465888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13466888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if (!success)
134670fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice            return false;
134680fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice
13469888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        if (auto_advance_pc && (after_pc_value == orig_pc_value))
13470888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        {
13471888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if (opcode_data->size == eSize32)
13472888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                after_pc_value += 4;
13473888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            else if (opcode_data->size == eSize16)
13474888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                after_pc_value += 2;
13475888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
13476888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            EmulateInstruction::Context context;
13477888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            context.type = eContextAdvancePC;
13478888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            context.SetNoArgs();
13479888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13480888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton                return false;
13481888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
13482888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        }
134830fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    }
134840fe5a535b87841a5c422f4a79d55c21bf07b50caCaroline Tice    return true;
1348564c8443d255f44267490c8c839f4a9365cf55ea7Greg Clayton}
134866b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
134876b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Ticebool
13488dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline TiceEmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
134896b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice{
13490dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if (!test_data)
134916b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13492dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation: Missing test data.\n");
134936b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
134946b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
13495dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice
13496dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    static ConstString opcode_key ("opcode");
13497dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    static ConstString before_key ("before_state");
13498dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    static ConstString after_key ("after_state");
13499dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice
13500dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
135016b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
135026b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    uint32_t test_opcode;
13503dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
135046b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13505dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
135066b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
135076b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
13508dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    test_opcode = value_sp->GetUInt64Value ();
135096b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
135106b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    if (arch.GetTriple().getArch() == llvm::Triple::arm)
135116b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
135126b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        m_opcode_mode = eModeARM;
135136b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        m_opcode.SetOpcode32 (test_opcode);
135146b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
135156b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
135166b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
135176b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        m_opcode_mode = eModeThumb;
135186b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        if (test_opcode < 0x10000)
135196b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice            m_opcode.SetOpcode16 (test_opcode);
135206b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        else
135216b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice            m_opcode.SetOpcode32 (test_opcode);
135226b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
135236b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
135246b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    else
135256b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13526dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation:  Invalid arch.\n");
135276b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
135286b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
135296b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
135306b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    EmulationStateARM before_state;
135316b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    EmulationStateARM after_state;
135326b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
13533dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    value_sp = test_data->GetValueForKey (before_key);
13534dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
135356b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13536dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
135376b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
135386b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
13539dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice
1354057b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13541dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if (!before_state.LoadStateFromDictionary (state_dictionary))
135426b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13543dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
135446b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
135456b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
135466b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
13547dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    value_sp = test_data->GetValueForKey (after_key);
13548dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
135496b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13550dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13551dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        return false;
135526b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
13553dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice
1355457b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    state_dictionary = value_sp->GetAsDictionary ();
13555dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if (!after_state.LoadStateFromDictionary (state_dictionary))
135566b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13557dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
135586b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
135596b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
13560dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice
135616b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    SetBaton ((void *) &before_state);
135626b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
135636b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice                  &EmulationStateARM::WritePseudoMemory,
135646b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice                  &EmulationStateARM::ReadPseudoRegister,
135656b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice                  &EmulationStateARM::WritePseudoRegister);
135666b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
13567888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
135686b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    if (!success)
135696b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    {
13570dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
135716b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice        return false;
135726b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    }
135736b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice
135746b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    success = before_state.CompareState (after_state);
13575dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice    if (!success)
13576dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice        out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13577dfb2e20724a90a4a10558ddaee18b72a1c51e499Caroline Tice
135786b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice    return success;
135796b8d3b5e7f0507aca2ee1c0937d7ec80fa2a9c5bCaroline Tice}
13580c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//
13581c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//
13582c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//const char *
13583c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13584c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//{
13585c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    if (reg_kind == eRegisterKindGeneric)
13586c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    {
13587c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        switch (reg_num)
13588c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        {
13589c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13590c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13591c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13592c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13593c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13594c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        default: return NULL;
13595c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        }
13596c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    }
13597c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    else if (reg_kind == eRegisterKindDWARF)
13598c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    {
13599c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//        return GetARMDWARFRegisterName (reg_num);
13600c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    }
13601c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//    return NULL;
13602c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//}
13603c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton//
13604c07d451bb046e47215bd73fda0235362cc6b1a47Greg Claytonbool
13605c07d451bb046e47215bd73fda0235362cc6b1a47Greg ClaytonEmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13606888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{
1360775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    unwind_plan.Clear();
13608c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13609c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
1361068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
13611c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
13612c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    // Our previous Call Frame Address is the stack pointer
1361368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (dwarf_sp);
13614c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
13615c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    // Our previous PC is in the LR
1361668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13617c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    unwind_plan.AppendRow (row);
13618c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
13619c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    // All other registers are the same.
13620c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton
13621c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    unwind_plan.SetSourceName ("EmulateInstructionARM");
1362237816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
1362337816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13624c07d451bb046e47215bd73fda0235362cc6b1a47Greg Clayton    return true;
13625888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton}
13626