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 ®_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 �0001� result = 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 when �1100� result = R[n] OR operand2; // ORR 12091061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1101� result = operand2; // MOV 12092061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1110� result = R[n] AND NOT(operand2); // BIC 12093061b79dbf1fefaf157d414747e98a463a0f32edaGreg Clayton when �1111� result = 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